home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / system / fdate84b.zip / FDATE.DOC < prev    next >
Text File  |  1994-05-04  |  122KB  |  3,107 lines

  1. FDATE                     Version 8.4b               April 2, 1994
  2. ======================================================================
  3. AUTHOR:     Stephen Ferg             
  4.             5113 N. 8th Road 
  5.             Arlington, VA 22205-1201
  6.             USA
  7.  
  8.             telephone (voice, not FAX): (703) 525-2241
  9.             CompuServe ID             : 73377,1157
  10.             Internet                  : 73377.1157@compuserve.com
  11.  
  12. =======================================================================
  13.  
  14.  
  15.  
  16.                              Table of Contents
  17.  
  18. Page numbers in the WordPerfect version of FDATE.DOC (which is not
  19. distributed with FDATE) are lost in the conversion to ASCII format. 
  20. Nevertheless, these page numbers give you a rough idea of the relative
  21. locations of the different sections.
  22.  
  23.   WHAT IS FDATE?. . . . . . . . . . . . . . . . . . . . . . . . . . . .   4
  24.      OTHER UTILITIES NAMED "FDATE". . . . . . . . . . . . . . . . . . .   5
  25.      OVERVIEW OF PARAMETERS . . . . . . . . . . . . . . . . . . . . . .   6
  26.      OVERVIEW OF FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . .   8
  27.   FUNCTIONS: DETAILED DESCRIPTIONS. . . . . . . . . . . . . . . . . . .  10
  28.      DATE FORMATTING FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  10
  29.      DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  11
  30.      MONTH DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . .  12
  31.      WEEKDAY DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . .  13
  32.      DATE/TIME COMPARISON FUNCTIONS . . . . . . . . . . . . . . . . . .  14
  33.      COMPARE-FUNCTION ERRORLEVELS . . . . . . . . . . . . . . . . . . .  14
  34.      NUMERIC ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . .  15
  35.      DATE VALIDATION FUNCTION . . . . . . . . . . . . . . . . . . . . .  17
  36.   STRING FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . . . . . .  18
  37.      GET and GETU (GET USER INPUT) FUNCTION . . . . . . . . . . . . . .  18
  38.      GETK (GET KEYPRESS) FUNCTION . . . . . . . . . . . . . . . . . . .  19
  39.        Specifying the Keymask . . . . . . . . . . . . . . . . . . . . .  19
  40.        GetK Results also in ERRORLEVEL. . . . . . . . . . . . . . . . .  20
  41.        Modifying the Keymask. . . . . . . . . . . . . . . . . . . . . .  21
  42.        Displaying a User Prompt With GETK . . . . . . . . . . . . . . .  21
  43.      SUBSTR (SUBSTRING) FUNCTION. . . . . . . . . . . . . . . . . . . .  22
  44.      LEN (LENGTH) FUNCTION. . . . . . . . . . . . . . . . . . . . . . .  23
  45.      UPPER FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . .  23
  46.      ECHO FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . .  23
  47.   DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  24
  48.      SYMBOL CONVENTIONS . . . . . . . . . . . . . . . . . . . . . . . .  24
  49.      PSEUDODATES. . . . . . . . . . . . . . . . . . . . . . . . . . . .  25
  50.   INPUT DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . .  26
  51.      CALENDAR DATE INPUT FORMATS. . . . . . . . . . . . . . . . . . . .  26
  52.      BUSINESS JULIAN DATE INPUT FORMATS . . . . . . . . . . . . . . . .  27
  53.      GETTING DATE/TIME A FILE WAS CREATED . . . . . . . . . . . . . . .  28
  54.   OUTPUT DATE FORMATS . . . . . . . . . . . . . . . . . . . . . . . . .  29
  55.      DAY-OF-WEEK AND MONTH OUTPUT FORMATS . . . . . . . . . . . . . . .  31
  56.      MISCELLANEOUS OUTPUT FORMATS . . . . . . . . . . . . . . . . . . .  31
  57.      LEAP-YEAR FLAG OUTPUT FORMAT . . . . . . . . . . . . . . . . . . .  32
  58.      TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . . . . . . . . .  32
  59.      BUSINESS JULIAN DATE OUTPUT FORMATS. . . . . . . . . . . . . . . .  33
  60.      ABSOLUTE DATE/TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . .  34
  61.      /T: TIME OVERRIDE PARAMETER. . . . . . . . . . . . . . . . . . . .  35
  62.   HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE. . . . . . . . .  36
  63.      CALL A BATCH FILE. . . . . . . . . . . . . . . . . . . . . . . . .  36
  64.      USE AN ENVIRONMENT-MANIPULATION UTILITY. . . . . . . . . . . . . .  36
  65.      FDATE'S /V PARAMETER . . . . . . . . . . . . . . . . . . . . . . .  37
  66.      /V WHEN RUNNING UNDER MICROSOFT WINDOWS. . . . . . . . . . . . . .  38
  67.        Turbo Professional: "Highly Recommended" . . . . . . . . . . . .  38
  68.      /V WHEN USING 4DOS, NDOS, AND UMB. . . . . . . . . . . . . . . . .  39
  69.   FDATE'S ERROR HANDLING. . . . . . . . . . . . . . . . . . . . . . . .  40
  70.   EXAMPLES OF HOW TO USE FDATE. . . . . . . . . . . . . . . . . . . . .  41
  71.      :01 Display Fdate output on screen . . . . . . . . . . . . . . . .  41
  72.      :02 Redirect FDATE output to a file. . . . . . . . . . . . . . . .  41
  73.      :03 Put FDATE output in an environment variable using a batch file  41
  74.      :04 Put FDATE output in an environment variable using /V parm. . .  41
  75.      :05 Put FDATE output in an environment variable using STRINGS. . .  41
  76.      :06 Put FDATE output in an environment variable using GET. . . . .  41
  77.      :07 Get user input . . . . . . . . . . . . . . . . . . . . . . . .  42
  78.      :08 Get a user menu selection. . . . . . . . . . . . . . . . . . .  43
  79.      :10 Change a date from one format into another . . . . . . . . . .  44
  80.      :11 Find the difference in days between two dates. . . . . . . . .  44
  81.      :12 Find the elapsed days/hours/minutes between two date/times . .  45
  82.      :14 Time the execution of a piece of software. . . . . . . . . . .  48
  83.      :15 Find calendar date corresponding to a "business Julian" date .  50
  84.      :16 Set your PC's date to a business julian date . . . . . . . . .  51
  85.      :18 Determine if parm %1 contains a valid date . . . . . . . . . .  53
  86.      :19 "Roll your own" date format  . . . . . . . . . . . . . . . . .  53
  87.      :20 Find the 4th Thursday in November (Thanksgiving) . . . . . . .  53
  88.      :22 On a date, show what anniversary it is for some event. . . . .  53
  89.      :23 Show a list of holidays in a given year. . . . . . . . . . . .  53
  90.      :24 Show a list of Federal holidays in a given year. . . . . . . .  53
  91.      :25 Determine if a year is valid, and evenly divisible by 4. . . .  54
  92.      :30 Compare a file's date to today's date. . . . . . . . . . . . .  54
  93.      :31 Compare two files' date/time . . . . . . . . . . . . . . . . .  55
  94.      :32 Display a list of all files that were created/updated today. .  56
  95.      :33 Delete files more than X days old (use a batch-file subroutine) 57
  96.      :34 Loop through an array of environment variables . . . . . . . .  62
  97.      :44 Do something on the last day (or last Friday) of the month . .  63
  98.      :45 Get information about the month prior to the current month . .  64
  99.      :50 Represent a date in 3 bytes of "extended hex" notation . . . .  65
  100.      :51 Represent a date in a short (4-byte) format (technique #1) . .  65
  101.      :52 Represent a date in a short (4-byte) format (technique #2) . .  66
  102.      :53 Convert numbers to . . . . . . . . . . . . . . . . . . . . . .  66
  103.      :54 Customize Fdate for a language of your choice. . . . . . . . .  67
  104.      :55 Fergian.BAT (used in the previous example) . . . . . . . . . .  68
  105.      :61 DO-ONCE: Run apps when booting for the first time of the day .  70
  106.      :62 Run specific software, depending on the day of the week. . . .  71
  107.      :63 Run a program at a specified time later in the day . . . . . .  71
  108.      :66 Change a filename to contain today's date. . . . . . . . . . .  73
  109.      :67 Change a file's name to a name that contains today's date. . .  73
  110.      :68 Change a file's name to a name containing an absolute minute .  73
  111.      :71 Extract the rightmost n characters of a string . . . . . . . .  73
  112.   HOW FDATE THINKS ABOUT DATES. . . . . . . . . . . . . . . . . . . . .  74
  113.      FDATE'S BUSINESS VIEW OF THE CALENDAR. . . . . . . . . . . . . . .  74
  114.      FDATE'S BASE DATE. . . . . . . . . . . . . . . . . . . . . . . . .  74
  115.      FDATE'S LEAP YEAR ALGORITHM. . . . . . . . . . . . . . . . . . . .  75
  116.      FDATE'S CENTURY-ASSUMPTION ALGORITHM . . . . . . . . . . . . . . .  76
  117.      FDATE'S IMPLEMENTATION LIMITS. . . . . . . . . . . . . . . . . . .  76
  118.   DISTRIBUTION ISSUES . . . . . . . . . . . . . . . . . . . . . . . . .  77
  119.      USE, REGISTRATION, AND DISTRIBUTION OF FDATE . . . . . . . . . . .  77
  120.      TECHNICAL SUPPORT FOR FDATE. . . . . . . . . . . . . . . . . . . .  78
  121.      WHERE TO FIND THE MOST CURRENT VERSION OF FDATE. . . . . . . . . .  78
  122.      UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS. . . . . . . . . . .  78
  123.      CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE. . . . . . . . . . . .  78
  124.      RECENT FDATE REVISION HISTORY. . . . . . . . . . . . . . . . . . .  79
  125.  
  126. WHAT IS FDATE?
  127. ==============
  128. Fdate is a utility for doing date formatting and date arithmetic in DOS
  129. batch files.  There are a number of different ways to put FDATE's output
  130. into environment variables.  Once this has been done, the environment
  131. variables can be used and manipulated in many ways in the batch file.
  132.  
  133. FDATE is freeware, or what is technically known as "zero-cost shareware". 
  134. There is no requirement to register FDATE in any way.  For more details,
  135. see the DISTRIBUTION ISSUES section.
  136.  
  137. Here are some of the things you can do with FDATE.
  138.  
  139.     accept user input from the keyboard
  140.  
  141.     retrieve today's date in a variety of formats
  142.       place today's date into a file name
  143.  
  144.     reformat dates 
  145.        Output formats include common American and European formats, or you
  146.        can "roll your own" by manipulating environment variables.  Month
  147.        and weekday names can be produced in several languages (English,
  148.        French, German, Spanish).
  149.  
  150.     calculate when certain holidays occur in a given year
  151.  
  152.     do date arithmetic
  153.       determine the date N days before/after a given date
  154.       compare two dates to determine which is earlier
  155.       compare two dates to determine how many days apart they are
  156.  
  157.     determine if a year is a leap year
  158.     determine whether a year is evenly divisible by some number
  159.  
  160.     determine what day of the week a date falls on
  161.       run certain software only on certain days of the week
  162.  
  163.     retrieve the date/time from the date/timestamp of a file
  164.     do simple integer arithmetic (add, subtract, modulus)
  165.     calculate the time a piece of software takes to run
  166.     convert a calendar date to/from a "business julian" date
  167.  
  168.     extract a substring from an environment variable
  169.  
  170.  
  171. OTHER UTILITIES NAMED "FDATE"
  172. =============================
  173.  
  174. There is another shareware utility named FDATE in circulation.  It is an
  175. implementation of the UNIX "touch" utility, and is used to change the
  176. date/time stamp of a file.  
  177.  
  178. Both FDATEs have been in circulation for too long to make it practical to
  179. change the name of either one.  All that can be done is to warn you of a
  180. potentially confusing situation.
  181.  
  182. OVERVIEW OF PARAMETERS
  183. ======================
  184.  
  185. FDATE accepts the following parameters:
  186.  
  187.        /F /A /B /I /O /P /S /N /D /L /V /T /Q
  188.  
  189. If the /F parameter is not present, FDATE displays a help screen.  
  190.      If you get FDATE's help screen when you don't expect it, you probably
  191.      forgot to specify the /F parameter or mistyped it.
  192.  
  193. Parameters can be in any order and upper or lower case.
  194.      Note that although function and format parms are not case sensitive,
  195.      they are "text sensitive".  If any characters are missing, added, or
  196.      mistyped, the parameter will be rejected.
  197.  
  198. What parameters are required (other than /F) depends on the function
  199. requested with the /F parameter.  Unnecessary parameters are simply
  200. ignored.
  201.  
  202.  
  203.  
  204. The next page contains a brief description of what each of the parameters
  205. means.
  206.  
  207. /F   requests a particular FDATE function.  This is Fdate's most important
  208.      parameter.  See the OVERVIEW OF FUNCTIONS section, and the detailed
  209.      description of each Fdate function.
  210.  
  211. /N   number of days (always a number)
  212.  
  213. /D   day-of-week number (used only with W function)
  214.  
  215. /A   For date functions, these two parameters are used to specify dates. 
  216. /B   For the ordinary arithmetic functions, these parameters are used to
  217.      specify numbers.  For date functions, if either of these parameters is
  218.      omitted, it defaults to today's date.
  219.  
  220. /T   For date functions, /T overrides the time portion of the date on the
  221.      /A parm. (Note that it does NOT override the time portion of the date
  222.      on the /B parm.)  
  223.  
  224. /I   specifies format of input date(s)
  225.      If the /I parameter is omitted, /Imm-dd-ccyy is assumed.
  226.  
  227. /O   specifies format of output date
  228.      If the /O parameter is omitted, /Od1 is assumed.
  229.  
  230. /L  specifies language of output.
  231.      /Lus   US (American) English-language output
  232.      /Lfr   French-language output
  233.      /Lgr   German-language output
  234.      /Lsp   Spanish-language output
  235.      If the /L parameter is omitted, /Lus [American English] is assumed.
  236.  
  237. /V   specifies that output is to be placed in an environment variable
  238.      rather than written to standard output.
  239.      If /V is specified but not followed by the name of an environment
  240.      variable, then /Vfdate is assumed, and output is placed in the FDATE
  241.      environment variable.
  242.  
  243. /Q   specifies a prompt string for a GET, GETU, or GETK function, or the
  244.      input string for a string-handling function (SUBSTR, LEN, UPPER).
  245.  
  246. /P   specifies a prefix string for the output
  247. /S   specifies a suffix string for the output
  248.      These optional parameters may always be specified or omitted.
  249.      They must be enclosed in single quotes, double quotes, or
  250.                   square brackets
  251.  
  252.      Note that "whitespace" will be removed from these strings, so
  253.      formatting of /P and /S strings cannot be controlled using spaces.  To
  254.      format strings, use periods or ASCII 255 (hex'ff') as filler.
  255.  
  256.        EXAMPLES
  257.           FDATE /Ff                /P"Today is "
  258.           FDATE /Fdif /B12-25-TTTT /P"It is " /S" days until Christmas"
  259.  
  260. OVERVIEW OF FUNCTIONS
  261. =====================
  262.  
  263. Fdate's most important parameter is the function parameter, /F.  Here is a
  264. brief summary of the functions that may be specified on the /F parm, for
  265. example: /Fadd.  Detailed descriptions of each of the functions can be
  266. found on the next few pages.
  267.  
  268. If the /F parameter is omitted, it defaults to the null string, which
  269. causes Fdate to display its HELP screens.
  270.  
  271. f         Format the date in the /A parm into format specified in /O parm
  272.  
  273. add       Add the number of days in the /N parm to the date in the /A parm
  274.  
  275. sub       Subtract the number of days in the /N parm from the date in the
  276.           /A parm
  277.  
  278. dif       Return the number of days between dates in the /A and /B parms
  279.  
  280. w         Do date arithmetic in terms of weeks rather than days.  Using the
  281.           date in the /A parm, a number specified in the /N parm, and a
  282.           day-of-the-week number specified in the /D parm, return the date
  283.           of the /Nth /Day-of-the-week before (or after) /Adate.  
  284.  
  285. m         Do date arithmetic in terms of months rather than days.  Add the
  286.           number of months in the /N parm to the date in the /A parm.  /N
  287.           may be a negative number.
  288.  
  289. STRING-HANDLING FUNCTIONS
  290.  
  291. get       get user input from the keyboard, and produce it as output
  292.           Optionally, display a prompt string.
  293.  
  294. getu      same as get, but produce output converted to upper case
  295.  
  296. getk      get a keypress and produce it (converted to upper case)
  297.  
  298. len       produce the length of a string in the /Q parm
  299.  
  300. upper     convert the string in the /Q parm to upper case
  301.  
  302. e         Echo the strings on the /P and /S parameters.
  303.  
  304. substr    Extract a substring from the /Q parm, starting in column
  305.           specified on /A parm, for a length specified on /B parm.
  306.  
  307. DATE/TIME COMPARISON FUNCTIONS
  308.  
  309. comp      Compare the dates in the /A and /B parms. Return LT, EQ, or GT.
  310.  
  311. tcomp     Compare the times specified on the /A and /B parms.
  312.  
  313.  
  314. ORDINARY (AS OPPOSED TO DATE) ARITHMETIC FUNCTIONS
  315.  
  316.           Functions whose names begin with "#" do ordinary arithmetic, i.e.
  317.           arithmetic on numbers rather than dates.
  318.  
  319. #add      Add the integers specified on the /A and /B parms.  To do
  320.           subtraction, add a negative number to a positive number.
  321.  
  322. #dif      returns the difference between the integers specified on the /A
  323.           and /B parms. 
  324.  
  325. #comp     Compare the integers specified on the /A and /B parms.  Return
  326.           LT, EQ, or GT.
  327.  
  328. #mod      Modulus.  Divide the integer on the /A parm by the integer on the
  329.           /B parm, and return the remainder.  
  330.  
  331. #mult     Multiply the integer on the /A parm by the integer on the /B
  332.           parm, and return the result.
  333.  
  334. #div      Divide the integer on the /A parm by the integer on the /B parm,
  335.           and return the result as a decimal number with two decimal
  336.           places.
  337.  
  338. #idiv     Integer division. Divide the integer on the /A parm by the
  339.           integer on the /B parm, and return the result as an integer.
  340.  
  341. #2xx      Convert an integer in the range of 0-35 to "extended hex" (XX)
  342.           notation.
  343.  
  344. FUNCTIONS: DETAILED DESCRIPTIONS
  345. ================================
  346.  
  347.  
  348. DATE FORMATTING FUNCTIONS
  349. =========================
  350.  
  351. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat
  352. --------  -------------------------------------------
  353. format    this is a synonym for function "f"
  354.  
  355. f         returns /Adate in format specified by /Oformat
  356.           Since /Aformat and /Oformat can be different, the FORMAT
  357.           function is used to change a date from one format to another.
  358.           Because of the wide variety of output formats, the FORMAT
  359.           function can also be used to determine the day of week of the
  360.           date, whether the date is in a normal or leap year, etc.
  361.  
  362. EXAMPLES
  363.           FDATE /Ff /A19920101 /Iccyymmdd /O"mn zd, ccyy"
  364.           FDATE /Ff       /Atoday         /Od1
  365.           FDATE /Fformat  /Atoday         /Od1
  366.           FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  367.  
  368. DATE ARITHMETIC FUNCTIONS
  369. =========================
  370.  
  371. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  372. which means that Fdate can accept numbers up to 9 digits long.
  373.  
  374. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  375. --------  -------------------------------------------
  376. add       Adds      /Ndays to   /Adate, produces date in /Oformat format
  377. sub       Subtracts /Ndays from /Adate, produces date in /Oformat format
  378.  
  379.           EXAMPLES
  380.           FDATE /Fadd /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  381.           FDATE /Fsub /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  382.           FDATE /Fadd /N90 /Atoday                   /Od1
  383.  
  384. dif       Returns number of days between /Adate and /Bdate
  385.           Order of the two dates is not significant.
  386.  
  387.           NOTE THAT:
  388.           For DIF, both dates must be in the SAME format, the input format
  389.           specified in /Iformat.  If the two dates are not in the same
  390.           format, you must first reformat one of the dates using the /Ff
  391.           function, then use DIF to get their difference.
  392.  
  393.           EXAMPLES
  394.           FDATE /Fdif /A01-01-1992 /B11-11-1992  /Imm-dd-ccyy
  395.           FDATE /Fdif /A11-11-1992 /B01-01-1992  /Imm-dd-ccyy
  396.           FDATE /Fdif /Atoday      /B01-01-1992  /Imm-dd-ccyy
  397.  
  398. MONTH DATE ARITHMETIC FUNCTIONS
  399. ===============================
  400.  
  401. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  402. --------  -------------------------------------------
  403. m         [month arithmetic]
  404.  
  405.           This function adds /N months to /Adate, and produces a date in
  406.           /Oformat format.  It can be used to do monthly subtraction by
  407.           making the number in the /N parameter a negative number.
  408.  
  409.           EXAMPLES
  410.  
  411.           FDATE /Fm /N1  /A03-15-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  412.                   produces:   04-15-1992
  413.  
  414.           FDATE /Fm /N-1 /A03-30-1991 /Imm-dd-ccyy /Omm-dd-ccyy
  415.                   produces:   02-28-1991
  416.  
  417.           FDATE /Fm /N-1 /A03-30-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  418.                   produces:   02-29-1992
  419.  
  420.  
  421.           Note that a too-simple algorithm for month arithmetic can produce
  422.           non-existent dates.  Subtracting a month from March 30, 1991 (as
  423.           in the second example) could produce a result of February 30,
  424.           1991, a date which cannot exist.  
  425.  
  426.           Fdate's month arithmetic is more sophisticated than that.  If
  427.           Fdate finds that a simple month-arithmetic operation produces an
  428.           invalid date, it subtracts the minimum number of days required to
  429.           produce a valid date.  
  430.  
  431.           Thus, in the second example, it produces February 28, 1991, the
  432.           last date in February, 1991.  In the third example, it produces
  433.           February 29, 1992 because 1992 is a leap year.  
  434.  
  435.  
  436. Note that telling Fdate to add 12 months to February 29, 1992 produces a
  437. result of February 28, 1993, since 1993 is not a leap year.  See Peter G.
  438. Neumann's INSIDE RISKS column in COMMUNICATIONS OF THE ACM, June 1992 (Vol.
  439. 35, No. 6), entitled "Leap-Year Problems":
  440.  
  441.   Prime Computer's MAGSAV failed at midnight [on Feb 29, 1992]...  G. M.
  442.   Lack noted that MAGSAV probably failed on leap-day because it tried to
  443.   increment the year by one to set a tape label expiration date, and the
  444.   resulting nonexistent date of Feb 29, 1993 threw it for a loop.
  445.  
  446. WEEKDAY DATE ARITHMETIC FUNCTIONS
  447. =================================
  448.  
  449. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat /Ddow#  /Ndow-count
  450. --------  -----------------------------------------------------------
  451. w         [week arithmetic]
  452.           This function provides a way of doing date arithmetic in terms of
  453.           weeks rather than days.
  454.  
  455.           This function accepts a date specification in parm /A and
  456.           returns the date of the /Nth /Day-of-the-week
  457.           before or after /Adate.  For example:
  458.  
  459.           If    /A specifies November 14, 1992
  460.                 /D specifies the number for Thursday (i.e., 5)
  461.                 /N specifies a week count of 3
  462.           then /Fw returns the date of the third Thursday after
  463.           November 14, 1992. (See full example, below)
  464.  
  465.           Note that /N may be negative.  If, in the above example, /N
  466.           is specified as -3, then Fdate returns the date of the third
  467.           Thursday BEFORE November 14, 1992.
  468.  
  469.           If the date specified on the /A parms falls on the same day
  470.           of the week as was specified on the /D parm, then that will
  471.           be considered to be the first date meeting that day-of-week
  472.           criterion.  That is, if November 14, 1992 fell on a
  473.           Thursday, and if /N was 1 or -1, then the output date would
  474.           be the same as the input date, i.e.  November 14, 1992.
  475.  
  476.           The acceptable values for /N (number of weeks) is in
  477.           the range of 99..-99.  A value of zero (i.e. /N0) is invalid.
  478.  
  479. EXAMPLES
  480.      find date of Thanksgiving (4th Thursday in November) in 1992
  481.          FDATE /Fw /A11-01-1992 /Imm-dd-ccyy /D5 /N4 /Od1
  482.      returns: Thursday November 26, 1992
  483.  
  484.      find the beginning of the work-week (Monday, 2nd day of week)
  485.      AFTER Thanksgiving, 1992
  486.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N1 /Od1
  487.  
  488.      find the beginning of the work-week (Monday, 2nd day of week)
  489.      BEFORE Thanksgiving, 1992
  490.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N-1 /Od1
  491.  
  492.      get last Friday's date
  493.         rem Find next Friday's date (or today's date, if today is Friday).
  494.         rem Then find the Friday that precedes that Friday.
  495.         FDATE /Fw /At        /Omm-dd-ccyy  /D6 /N+1  /V
  496.         FDATE /Fw /A%fdate%  /Imm-dd-ccyy  /D6 /N-2  /V
  497.         Echo Last Friday was %fdate%
  498.  
  499. DATE/TIME COMPARISON FUNCTIONS
  500. ==============================
  501.  
  502. FUNCTION  FDATE /Ffunc /Adate /Bdate /Iformat
  503. --------  -------------------------------------------
  504. comp      compares the dates (time granularity = 1 day)
  505.           specified on the /A and /B parms.
  506.           returns         when
  507.             LT            /A  is less than    (earlier than) /B
  508.             EQ            /A  is equal to     (same as)      /B
  509.             GT            /A  is greater than (later than)   /B
  510.  
  511.           In addition, the errorlevel is set to a special value:
  512.             LT = 101     EQ = 102     GT = 103
  513.  
  514.  
  515.  
  516. tcomp     compares the times (time granularity = 1 second)
  517.           specified on the /A and /B parms.
  518.           This is useful when input format /If (file) is specified.
  519.           It can be used to compare the timestamps of two files and
  520.           determine which is older.
  521.               EXAMPLE: Fdate /Ftcomp /If /Amyfile.1 /Byourfile.1
  522.  
  523.           returns         when
  524.             LT            /A  is less than    (earlier than) /B
  525.             EQ            /A  is equal to     (same as)      /B
  526.             GT            /A  is greater than (later than)   /B
  527.  
  528.           In addition, the errorlevel is set to a special value:
  529.             LT = 101     EQ = 102     GT = 103
  530.  
  531.  
  532.  
  533. COMPARE-FUNCTION ERRORLEVELS
  534. ============================
  535.  
  536. Starting with version 8.3, Fdate's "comparison" functions (comp, tcomp,
  537. #comp) return distinct errorlevels as well as distinct output strings:
  538.  
  539.           returns         errorlevel
  540.             LT            101
  541.             EQ            102
  542.             GT            103
  543.  
  544. NUMERIC ARITHMETIC FUNCTIONS
  545. ============================
  546.  
  547. Note that all of Fdate's arithmetic functions operate on integers.  A
  548. decimal number on an input parameter will be rejected, and an error message
  549. will be displayed.
  550.  
  551. FUNCTION  FDATE /Ffunc /Anum  /Bnum
  552. --------  -------------------------------------------
  553.  
  554. #add      returns the sum of the integers specified
  555.           on the /A and /B parms.  Can be used to calculate the
  556.           "absolute" minute(second, date) in the future from a given
  557.           "absolute" minute(second, date).   Also useful in generating
  558.           sequences of numbers and looping (see EXAMPLES).
  559.  
  560. #sub      (not supported)
  561.           Fdate does not provide a numeric subtraction operation as such. 
  562.           To do subtraction, add two numbers, one of which is a negative
  563.           number.  For example, to subtract 3 from 2:
  564.               FDATE /F#add /A2 /B-3          [ returns: -1 ]
  565.  
  566. #dif      returns the difference between the integers specified on the /A
  567.           and /B parms.  #dif is the same as subtraction in which the
  568.           smaller number is subtracted from the larger number; it will
  569.           never return a negative number.  It can be used to calculate the 
  570.           number of minutes(seconds, days) between two "Absolute"
  571.           minutes(seconds, dates).
  572.  
  573. #comp     compares the integers specified on the /A and /B parms.
  574.           returns         when
  575.             LT            /A  is less    than /B
  576.             EQ            /A  is equal   to   /B
  577.             GT            /A  is greater than /B
  578.  
  579.           In addition, the errorlevel is set to a special value:
  580.             LT = 101     EQ = 102     GT = 103
  581.  
  582. #mod      divides the integer on the /A parm by the integer on the /B parm,
  583.           and returns the remainder.  
  584.  
  585.           This is useful for determining whether a number is evenly
  586.           divisible by some other number.  If the remainder is 0, then /A
  587.           is evenly divisible by /B.  If a year is evenly divisible by 4,
  588.           for example, then it is an American election year.  If it is
  589.           evenly divisible by 100, then it is a century year, etc.
  590.  
  591.  
  592. #mult     multiplies the integer on the /A parm by the integer on the /B
  593.           parm, and returns the result.
  594.  
  595. #div      (division) divides the integer on the /A parm by the integer on
  596.           the /B parm, and returns the result as a decimal number, with two
  597.           digits to the right of the decimal.
  598.  
  599.           This is useful for dividing a number (representing the number of
  600.           minutes in some period) by 60 to get the length of the period
  601.           expressed in terms of hours, or by 1440 to get the length of the
  602.           period expressed in terms of days.  Or you could divide a number
  603.           of days by 7 to get the number of weeks, etc.
  604.  
  605.  
  606. #idiv     (integer division) divides the integer on the /A parm by the
  607.           integer on the /B parm, and returns the result as an integer.
  608.  
  609.           This is useful, especially in conjunction with the #mod function,
  610.           for converting a number of minutes into a number of hours and
  611.           minutes, or days and hours and minutes.  See the EXAMPLES
  612.           section, below.
  613.  
  614. #2xx      (convert number to "extended hex" format)
  615.           "Extended hexadecimal" (XX) notation uses all of the digits, and
  616.           all of the letters of the alphabet, to express numbers in the
  617.           range of 0 to 35 as a single character.  
  618.  
  619.           This function takes a number supplied on parameter /A, and
  620.           returns a single character in extended hex notation.  The input
  621.           number should be in the range of 0-35.  A number of less than 0
  622.           or larger than 35 is rejected as an error (returns "ERROR" and
  623.           errorlevel of 1).
  624.  
  625.           EXAMPLE: Fdate /F#2xx /A35    =====> returns the letter Z
  626.  
  627. DATE VALIDATION FUNCTION
  628. ========================
  629.  
  630. v    If the date specified on the /A parm is valid, produces "" (the null
  631.      string).  Otherwise, produces "ERROR" and a non-zero errorlevel by
  632.      triggering Fdate's error-handling function.  (See the section on
  633.      FDATE'S ERROR HANDLING, later in this documentation.)
  634.  
  635.      When using the /Fv parameter, you will almost always want to check
  636.      success of the date validation by checking the errorlevel, and to
  637.      redirect Fdate's output to NUL (so that when it writes the null
  638.      string, it does not produce a blank line on your screen).
  639.  
  640.      When processing an input date, Fdate does not reject all invalid
  641.      dates: specifically, it is very forgiving about the number in the day-
  642.      of-the-month part of input dates.  It will accept, for example,
  643.      19931144 (November 44, 1993 in CCYYMMDD format) and process it quite
  644.      happily (as December 14, 1993).  This is not a bug, it is a feature. 
  645.      This feature provides one way (admittedly a crude one) of doing date
  646.      arithmetic.  The date part (JJJ) of a Business Julian input date can
  647.      be used in the same way.  
  648.  
  649.      This feature can be a drawback, however, if you want to be sure that
  650.      some date (say a date that a user entered as an input parameter) is
  651.      valid.  The /Fv function provides a way of completely checking a date
  652.      for validity.  It will, for example, reject November 44, 1993 as
  653.      invalid. 
  654.  
  655.  
  656. STRING FUNCTIONS
  657. ================================
  658.  
  659. GET and GETU (GET USER INPUT) FUNCTIONS
  660. =======================================
  661.  
  662. get  get user input
  663. getu get user input (uppercase)
  664.  
  665.      These functions wait for the user to enter an input string, terminated
  666.      by a press of the ENTER key.  Then Fdate simply produces that same
  667.      input string (or in the case of GETU, that input string in all upper
  668.      case) as its output.  
  669.  
  670.      If the /Q prompt-string parameter is specified, then the prompt string
  671.      is displayed, but a NEWLINE is not written to the screen before
  672.      waiting for the user's input.
  673.  
  674.      As with Fdate's other forms of output, this output can be displayed,
  675.      redirected to a file, or (if your environment supports Fdate's /V
  676.      parameter) placed into an environment variable.
  677.  
  678.      This "get" function provides no edit mask for input -- Fdate will
  679.      accept anything.  The situation is helped by the fact that Fdate also
  680.      provides a validate function (/Fv) which can be used to validate the
  681.      user input, so that one can:
  682.  
  683.           1.   use /Fget to get user input and place it in an environment
  684.                variable 
  685.           2.   use /Fv to validate the date in the Evar
  686.           3.   use the rest of the batch file to process the user input
  687.  
  688.      See examples: "Get user input" and FORATIM2.BAT
  689.  
  690.      For a program that provides more sophisticated functions for getting
  691.      user input in batch files (type checking, edit masks, etc.), I
  692.      recommend Bob Stephan's shareware program GET, which is described
  693.      elsewhere in this documentation.
  694.  
  695. GETK (GET KEYPRESS) FUNCTION
  696. =======================================
  697. getK get keypress 
  698.  
  699.      This function waits for the user to press an acceptable key, then
  700.      produces the key as its output.  If the key pressed is a letter, then
  701.      the letter is returned IN UPPER CASE.  This feature is designed to
  702.      support simple "pick a menu selection" processing in batch files.
  703.  
  704.      The GETK function takes a /K "keymask" parameter that tells it which
  705.      keys to accept.  If the user presses an unacceptable key (i.e. one
  706.      that is not in the keymask), the keypress is ignored.
  707.  
  708.      If no /K parm is specified, the default keymask is:
  709.              ABCDEFGHIJKLMNOPQRSTUVWXYZx
  710.      That is, the default keymask will accept letters and the ESCAPE key.
  711.  
  712.   Specifying the Keymask
  713.  
  714.      NOTE THAT THE VALUES SPECIFIED ON THE /K PARM ARE CASE-SENSITIVE.  
  715.  
  716.      The keymask may contain numbers, uppercase letters, and any of the
  717.      other printable characters on the keyboard.  
  718.  
  719.      There is no way to tell FDATE to accept "special" keypresses such as
  720.      function keys, ALT or CONTROL keys, arrow keys, etc.
  721.  
  722.      If the keymask contains an uppercase letter (e.g. "A"), and the user
  723.      presses the corresponding unshifted letter (e.g. "a"), then the
  724.      keypress will be accepted and the uppercase letter will be returned.
  725.  
  726.      The keymask may contain the following lowercase letters, which have
  727.      special meanings:
  728.  
  729.        x  represents the ESCAPE key
  730.        e  represents the ENTER (RETURN) key
  731.        z  [a place-holder character]
  732.  
  733.             Lowercase "z" will be ignored when FDATE decides which
  734.             keypresses are acceptable.  Its presence in the keymask will
  735.             affect the positions of other characters in the keymask, and
  736.             hence the ERRORLEVEL that FDATE returns when the user presses
  737.             an acceptable key.  (For the uses of "z", see "GetK Results
  738.             also in ERRORLEVEL" and "Modifying the Keymask", below.)
  739.  
  740.      All other lowercase letters are reserved for possible future use.  In
  741.      the current release of FDATE, they are treated like lowercase "z".
  742.  
  743.      EXAMPLE:  If a keymask of "/kXx" was specified, then if the user
  744.                pressed the (shifted or unshifted) "X" key, then uppercase
  745.                "X" would be returned.  If he pressed the ESCAPE key, then
  746.                lowercase "x" would be returned.
  747.  
  748.   GetK Results also in ERRORLEVEL
  749.  
  750.      When the GETK function returns a key, it sets the DOS errorlevel to a
  751.      value corresponding to the position of that key in the keymask.  For
  752.      example, with keymask of "/kABx", if the user presses:
  753.  
  754.           "A": value returned will be "A", errorlevel will be 1
  755.           "B": value returned will be "B", errorlevel will be 2
  756.        ESCAPE: value returned will be "x", errorlevel will be 3
  757.  
  758.      If the user presses CONTROL+BREAK, FDATE will abort and return
  759.      errorlevel 255.
  760.  
  761.      Here is an example batch file:
  762.      ==================================================================
  763.      @echo off
  764.      cls
  765.      echo Demonstration of FDATE's GETK (get keypress) function
  766.      echo Press CONTROL+BREAK to end
  767.      :top
  768.      echo.
  769.      fdate /fGetK /P"You pressed: " /Q"Press a key: "  /K"12ABxe "
  770.      if errorlevel 1  if not errorlevel 2  echo errorlevel : 1
  771.      if errorlevel 2  if not errorlevel 3  echo errorlevel : 2
  772.      if errorlevel 3  if not errorlevel 4  echo errorlevel : 3
  773.      if errorlevel 4  if not errorlevel 5  echo errorlevel : 4
  774.      if errorlevel 5  if not errorlevel 6  echo errorlevel : 5
  775.      if errorlevel 6  if not errorlevel 7  echo errorlevel : 6
  776.      if errorlevel 7  if not errorlevel 8  echo errorlevel : 7
  777.      if errorlevel 255 echo ERRORLEVEL 255
  778.      if errorlevel 255 goto endit
  779.      goto top
  780.      :endit
  781.      ==================================================================
  782.  
  783.      Note that the keymask may contain blanks if the keymask is enclosed in
  784.      quotes (as in this example batch file).  But remember that Fdate
  785.      eliminates redundant spaces when obtaining its parameter input, so you
  786.      should never include more than one blank in your keymask.
  787.  
  788.   Modifying the Keymask
  789.  
  790.      It it is often necessary to make program modifications during the life
  791.      of a batch file.  If you are using the GETK function and testing the
  792.      errorlevel rather than the environment, then the insertion or deletion
  793.      of characters into the existing keymask will change the errorlevels
  794.      returned by the following characters in the keymask.  This will force
  795.      you to re-write the errorlevel tests, which may be a big job if the
  796.      keymask is long.
  797.  
  798.      Here are some tips on how to avoid this work:
  799.  
  800.          When ADDING a character to the keymask, always add it at the END
  801.           of the keymask.
  802.  
  803.          When DELETING a character from the keymask, do not actually
  804.           delete it.  Instead, replace it by a lowercase "z".
  805.  
  806.  
  807.  
  808.   Displaying a User Prompt With GETK
  809.  
  810.      The /Q (user prompt) parameter is especially handy when used in
  811.      conjunction with the GETK function.  If the /Q prompt-string parameter
  812.      is specified (as in the example batch file, above), then the prompt
  813.      string is displayed, but a NEWLINE is not written to the screen before
  814.      waiting for the user's keypress.
  815.  
  816.      For a program that provides more sophisticated "get key" functions for
  817.      batch files, I recommend Bob Stephan's shareware program GET, which is
  818.      described elsewhere in this documentation.
  819.  
  820. SUBSTR (SUBSTRING) FUNCTION
  821. ===============================
  822.  
  823. substr
  824.      This function returns a substring of the string supplied in the /Q
  825.      parm, starting in the column supplied in the /A parm, for a length
  826.      supplied in the /B parm.  
  827.  
  828.      The start column specified in the /A parm may be a negative number; if
  829.      it is, then the start column is calculated from the end of the string
  830.      rather than from the beginning.  This feature makes it easy to extract
  831.      the rightmost characters of a string.  
  832.  
  833.                Specifically, when the ParmA is negative, the start position
  834.                is calculated using the following formula:
  835.  
  836.                       StartColumn = length(ParmQ) + 1 + ParmA
  837.  
  838.                Example:   Fdate /Fsubstr  /A-2  /Qabcd
  839.                       StartColumn = length(ParmQ) + 1 + ParmA
  840.                       StartColumn =      4        + 1 + (-2)     = 3  
  841.  
  842.      If /Q is omitted, Fdate reports an error.
  843.  
  844.      If /A is zero, Fdate reports an error.
  845.      If /A is omitted, it defaults to 1 (that is, the start of the string).
  846.      If /A is negative,  and longer than the length of the string, then the
  847.                          start column is 1 (the start of the string)
  848.  
  849.      If /B (length) is so great that it exceed the length of the /Q input
  850.      string, then only the remainder of the string is returned.
  851.  
  852.      If /B is zero, Fdate returns a null string.
  853.      If /B is omitted, it defaults to 999.
  854.  
  855.      EXAMPLES:
  856.           Fdate /Fsubstr /A7 /B2 /Q"STEVE FERG"   ===> "FE"
  857.           Fdate /Fsubstr /A7     /Q"STEVE FERG"   ===> "FERG"    
  858.           Fdate /Fsubstr     /B5 /Q"STEVE FERG"   ===> "STEVE"   
  859.  
  860.      EXAMPLES using a negative start position:
  861.           Fdate /Fsubstr /a-6 /B3 /Q"1994 Jun 03"   ===> "Jun         
  862.  
  863.           rem extract the rightmost 6 characters of a string
  864.           Fdate /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  865.  
  866.      REMEMBER that Fdate eliminates redundant spaces when obtaining its
  867.      parameter input:
  868.  
  869.           Fdate /Fsubstr /A7     /Q"STEVE FERG"      ===> "FERG" 
  870.           Fdate /Fsubstr /A7     /Q"STEVE  FERG"     ===> "FERG" 
  871.           Fdate /Fsubstr /A7     /Q"STEVE    FERG"   ===> "FERG" 
  872.  
  873. LEN (LENGTH) FUNCTION
  874. =====================
  875.  
  876. len       Produces a number that is the length of the string on the /Q
  877.           parm.
  878.  
  879.  
  880. UPPER FUNCTION
  881. ===============
  882.  
  883. upper     Produces the string on the /Q parm, converted to upper case.
  884.  
  885.  
  886.  
  887. ECHO FUNCTION
  888. =============
  889.  
  890. e         Produces only the strings specified using the /P and /S
  891.           parameters.
  892.  
  893. You can use /Fe for situations in which you want Fdate to produce output
  894. that doesn't include any sort of date.  In these cases, Fdate functions
  895. just like the DOS "echo" command.  
  896.  
  897. The real use for /Fe is in conjunction with /V, where it can be used to
  898. manipulate the environment in ways that DOS's SET command cannot:
  899.  
  900.   (1)  to give a value to an environment variable that it would not accept
  901.        from the SET command (e.g. a value that contained "=").
  902.  
  903.   (2)  to redirect or pipe a character-string that contains a redirection
  904.        symbol ">" or pipe symbol "|".
  905.  
  906. This feature is for real batch-file power users.
  907.  
  908.  
  909. EXAMPLE BATCH FILE
  910. ------------------
  911.   @ECHO OFF
  912.   set pct=%%%
  913.   Fdate /Fe /P"=Sam=" /vName
  914.   Fdate /Fe /P"echo ECHO Hi, %pct%Name%pct%!>junk2.bat">junk1.bat
  915.      :  RESULT: TEXT OF JUNK1.BAT IS
  916.      :          echo ECHO Hi, %Name%!>junk2.bat
  917.   call junk1.bat
  918.      :  RESULT: TEXT OF JUNK2.BAT IS
  919.      :          ECHO Hi, =Sam=!
  920.   call junk2.bat
  921.      :  RESULT: TEXT DISPLAYED ON SCREEN IS
  922.      :          Hi, =Sam=!
  923.   :endit
  924.  
  925. DATE FORMATS
  926. ============
  927.  
  928. SYMBOL CONVENTIONS
  929. ==================
  930.  
  931. The following symbols are used in specifying date formats:
  932.  
  933. SYMBOL  EXAMPLE   MEANING
  934. ------  -------   -------------------------------------
  935. cc        19      century
  936. yy        93      year
  937. mm        02      month
  938. zm         2      month without leading zero
  939. dd        08      day
  940. zd         8      day   without leading zero
  941. mn       February month name
  942. mn3      Feb      month name, first 3 characters only
  943. dow      Tuesday  day of week
  944. dow3     Tue      day of week, first 3 characters only
  945. dow#      3       day of week as a number (Sunday=1, Monday = 2, etc.)
  946. today             is a "pseudodate" representing the current date
  947. t                 is an alias for the "today" pseudodate
  948. hh:mm    09:05    hours and minutes
  949. hhmm     0905     hours and minutes
  950. ss        13      seconds
  951.  
  952.  
  953.  
  954. PSEUDODATES
  955. ===========
  956.  
  957. t (or today)
  958.           can be used with either /A or /B, e.g. /Atoday or /At.
  959.           This is the default for both /A and /B.  That is, if /A is not
  960.           specified, /At is assumed, and the same for /B.
  961.  
  962.           NOTE THAT
  963.           "Today" as a date specification operates independently of any
  964.           input format.  You need to specify an input format (either
  965.           explicitly via the /I parameter, or implicitly by accepting the
  966.           default value of /I) only for input dates that are supplied to
  967.           Fdate in some other way than via the "today" pseudodate: as a
  968.           date literal, a filename, etc.
  969.  
  970. EXAMPLES:
  971.           rem Get the date that is 90 days from today
  972.           FDATE /Fadd /N90 /Atoday /Omm-dd-ccyy
  973.           FDATE /Fadd /N90 /At     /Omm-dd-ccyy
  974.  
  975.           rem determine if this year is a leapyear
  976.           FDATE /Ff /At /OLY
  977.  
  978.  
  979.  
  980.  
  981. tttt      When used in place of a 4-digit CCYY string, "tttt"
  982.           will cause Fdate to use today's 4-digit year (CCYY).
  983.  
  984. tt        When used in place of a 2-digit DD, MM, or YY string,
  985.           "tt" will cause Fdate to use today's day-of-the-month,
  986.           month, or 2-digit year, respectively.
  987.  
  988.           Note that "tt" can NOT be used for the YY portion of a CCYY
  989.           input year.  The following, for example, is NOT valid:
  990.                FDATE /Ff /Imm-dd-ccyy /A01-01-19tt /Od1
  991.  
  992. EXAMPLES:
  993.  
  994.      FDATE /Ff /Imm-dd-ccyy /A01-01-tttt
  995.      FDATE /Ff /Imm-dd-yy   /A01-01-tt 
  996.  
  997.      rem report the 15th day of this month, this year
  998.      FDATE /Ff /Imm-dd-ccyy /Att-15-tttt
  999.  
  1000.      rem Show the first Monday in the second quarter of this year
  1001.      FDATE /Fw /Iccyymmdd /Atttt0401 /D2 /N1  /P"First Monday in QTR#2: "
  1002.  
  1003.      rem Show the last Friday on/before the 15th of this month.
  1004.      FDATE /Fw /Iccyymmdd /Atttttt15 /D6 /N-1 /P"Friday before the 15th: "
  1005.  
  1006.  
  1007. INPUT DATE FORMATS
  1008. ==================
  1009.  
  1010.  
  1011. CALENDAR DATE INPUT FORMATS
  1012. ===========================
  1013.  
  1014. FORMAT      EXAMPLES      DISCUSSION
  1015. ------      ---------     -----------------------------
  1016. ccyymmdd    19922002  
  1017.  
  1018.  
  1019. On the /I (input format) parm, the separator character of the following
  1020. input formats must be a dash.  This simply tells Fdate that the input
  1021. date will contain SOME separator character.  The separator character that
  1022. actually occurs in dates in the /A and /B parms is ignored, and may be
  1023. any non-numeric character: a slash "/", a dash "-", a dot ".", etc.
  1024.  
  1025. In specifications that begin with "mm-dd" or "dd-mm", leading zeros need
  1026. not be present in the "mm" and "dd" part of the date.
  1027.  
  1028. ccyy-mm-dd  1992-02-20    Leading zeros MUST be present, since the
  1029.             1992/02/20    date does not begin with dd-mm or mm-dd.    
  1030.             1992.02.20    
  1031.  
  1032.  
  1033. mm-dd-ccyy  02-20-1992    
  1034.             02/20/1992    The dash represents ANY non-numeric character.
  1035.  
  1036.              2-5-1992     Leading zeros need not be present.
  1037.              2/5/1992
  1038.  
  1039. mm-dd-yy    02-05-92      February 5, 1992.  See discussion of
  1040.              2/5/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1041.  
  1042.                           ---------------------------------------
  1043.                           In the following formats, days
  1044.                           precede months  (European style)
  1045.                           ---------------------------------------
  1046.  
  1047. dd-mm-ccyy  05-02-1992 
  1048.             05/02/1992 
  1049.  
  1050.              5-2-1992     Leading zeros need not be present.
  1051.              5/2/1992
  1052.  
  1053. dd-mm-yy    05-02-92      February 5, 1992.  See discussion of
  1054.              5/2/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1055.  
  1056. BUSINESS JULIAN DATE INPUT FORMATS
  1057. ==================================
  1058.  
  1059. These are formats for "business julian" dates: dates expressed as the
  1060. number of days from the beginning of the year, when January 1 is day 1.
  1061.  
  1062. EXAMPLES:
  1063.  
  1064.       date      BUSINESS JULIAN DATE
  1065.   -----------   --------------------
  1066.   Jan  5, 1992  92005
  1067.   Jan  5, 1993  93005
  1068.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1069.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1070.  
  1071. -----------------------------------------------------------------------
  1072. NOTE:   * JJJ can be 1 - 4 digits
  1073.         * may include a prefix of a plus or minus ( + or - ) sign
  1074. -----------------------------------------------------------------------
  1075.  
  1076. FORMAT      EXAMPLES      DISCUSSION
  1077. ------      ---------     -----------------------------
  1078. ccyyjjj     1992003       Third day of 1992, i.e. Jan 3, 1992
  1079.             19923         Third day of 1992
  1080.             tttt003       Third day of this year
  1081.             tttt3         Third day of this year
  1082.  
  1083.   yyjjj       92003       Third day of 1992
  1084.               923         Third day of 1992
  1085.               tt003       Third day of this year
  1086.               tt3         Third day of this year
  1087.               01003       Third day of 2001           See
  1088.                           FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1089.  
  1090. NOTE THAT FDATE WILL ACCEPT "JJJ" OF LESS THAN 1 & MORE THAN 366.
  1091. -----------------------------------------------------------------
  1092.  
  1093.   yyjjj       tt1000      the 1000th day from beginning of this year
  1094.               tt0         last day of last year
  1095.               tt-1        next-to-last day of last year
  1096.  
  1097. FDATE /Ff /Iccyyjjj /Od1 /A1992-1  produces... Monday December 30, 1991
  1098. FDATE /Ff /Iccyyjjj /Od1 /A19920   produces... Tuesday December 31, 1991
  1099. FDATE /Ff /Iccyyjjj /Od1 /A1992+1  produces... Wednesday January 1, 1992
  1100.  
  1101. FDATE /Ff /Iccyyjjj /Od1 /A1992366 produces... Thursday December 31, 1992
  1102. FDATE /Ff /Iccyyjjj /Od1 /A1992367 produces... Friday January 1, 1993
  1103.  
  1104. This feature allows limited date arithmetic with ordinary business
  1105. Julian days.  For example, 90 days from tt300 can be shown by:
  1106.  
  1107.                   FDATE /Ff /Iyyjjj /Att390
  1108.  
  1109. GETTING DATE/TIME A FILE WAS CREATED
  1110. ====================================
  1111.  
  1112. FORMAT      EXAMPLES      DISCUSSION
  1113. ------      ---------     -----------------------------
  1114. f           MYFILE.1      Input format F (file) tells Fdate that
  1115.                           /A and /B will specify filenames, and that
  1116.                           Fdate should pick up the input date and time
  1117.                           from the date/time stamp on a file.
  1118.  
  1119.      Note that if you specify /If, then both /A and /B will be interpreted
  1120.      as filenames.
  1121.  
  1122.      It is not possible to put a filename in /A and a date literal in /B,
  1123.      and then use the "comp" or "dif" function to compare them.  You must
  1124.      first extract the file's date into an environment variable, and then
  1125.      compare that environment variable to the date literal.
  1126.  
  1127.           The only exception to this rule is the pseudodate "t" (i.e. /At
  1128.           or /Bt) which will pick up the current date and time from the
  1129.           system clock.  This feature will allow you, for example, to
  1130.           compare the date of a file to today's date (see EXAMPLES).
  1131.  
  1132.      A filename may (but need not) be fully qualified: i.e. "MYFILE.1" and
  1133.      "C:\DBASE\WORKDIR\MYFILE.1" are both acceptable.
  1134.  
  1135.      A filename may contain wildcards.  If it does, the date/time stamp
  1136.      will be retrieved from the first file that FDATE finds that meets the
  1137.      filespec.  Giving FDATE a filespec containing a wildcard is pretty
  1138.      useless, but FDATE will not reject it.
  1139.  
  1140. OUTPUT DATE FORMATS
  1141. ===================
  1142.  
  1143. FORMAT        EXAMPLES      DISCUSSION
  1144. ------        ---------     -----------------------------
  1145. dd-mn3-yy     08-Feb-92     CompuServe-style date
  1146.   yy            93          2-digit year number
  1147. ccyy          1993          4-digit year number (includes century)
  1148. ccyymm        199302        useful for triggering monthly processing
  1149. ccyymmdd      19930208      useful for putting current date in filename
  1150.   yymmdd        908208      useful for putting current date in filename
  1151.     mmdd          0208
  1152.       mm            02      2-digit month number
  1153.       zm             2      month number, no leading zeros
  1154.       dd            08      2-digit day-of-month number
  1155.       zd             8      day-of-month number, no leading zeros
  1156.  
  1157. In the following formats, months precede days (American style)
  1158. ------------------------------------------------------------------
  1159. mm/dd/ccyy    02/08/1993
  1160. mm-dd-ccyy    02-08-1993
  1161. mm.dd.ccyy    02.08.1993    British-style dates
  1162.  
  1163. zm/zd/ccyy     2/8/1993     no leading zeros in day or month
  1164. zm-zd-ccyy     2-8-1993     no leading zeros in day or month
  1165. zm.zd.ccyy     2.8.1993     British-style dates
  1166.  
  1167. mm/dd/yy      02/08/92
  1168. mm-dd-yy      02-08-92
  1169. mm.dd.yy      02.08.92      British-style dates
  1170.  
  1171. zm/zd/yy       2/8/92       no leading zeros in day or month
  1172. zm-zd-yy       2-8-92       no leading zeros in day or month
  1173. zm.zd.yy       2.8.92       no leading zeros in day or month
  1174.  
  1175.  
  1176.  
  1177. In the following formats, days precede months  (European style)
  1178. ------------------------------------------------------------------
  1179.  
  1180. ddmmccyy      02081993
  1181. ddmmyy        020893
  1182.  
  1183. dd/mm/ccyy    02/08/1993
  1184. dd-mm-ccyy    02-08-1993
  1185. dd.mm.ccyy    02.08.1993    British-style dates
  1186.  
  1187. zd/zm/ccyy     2/8/1993     no leading zeros in day or month
  1188. zd-zm-ccyy     2-8-1993     no leading zeros in day or month
  1189. zd.zm.ccyy     2.8.1993     British-style dates
  1190.  
  1191. dd/mm/yy      02/08/93
  1192. dd-mm-yy      02-08-93
  1193. dd.mm.yy      02.08.93      British-style dates
  1194.  
  1195. zd/zm/yy       2/8/93       no leading zeros in day or month
  1196. zd-zm-yy       2-8-93       no leading zeros in day or month
  1197. zd.zm.yy       2.8.93       British-style dates
  1198.  
  1199. DAY-OF-WEEK AND MONTH OUTPUT FORMATS
  1200. ====================================
  1201.  
  1202. dow#           5            Sunday=1, Monday=2 .... Saturday=7.
  1203.  
  1204. dow            Thursday     name of day of week
  1205.                jeudi        if /Lfr specified
  1206.                Donnerstag   if /Lgr specified
  1207.  
  1208. dow3           Thu          first 3 characters of name of day of week
  1209.                jeu          if /Lfr specified
  1210.                Don          if /Lgr specified
  1211.  
  1212. mn             February     name of month
  1213.                fevrier      if /Lfr specified
  1214.                Februar      if /Lgr specified
  1215.  
  1216. mn3            Feb          first 3 characters of name of month
  1217.                fev          if /Lfr specified
  1218.                Feb          if /Lgr specified
  1219.  
  1220.  
  1221.  
  1222. MISCELLANEOUS OUTPUT FORMATS
  1223. ============================
  1224.  
  1225. full      9:05 pm on Wednesday February 5, 1992
  1226.           9:05 pm, mercredi le 5 fevrier 1992  [/Lfr specified]
  1227.           9:05 pm, miércoles el 5 de febrero de 1992 [/Lsp specified]
  1228.           Mittwoch, 5. Februar 1992, 21:05     [/Lgr specified]
  1229.  
  1230. d1        Saturday, February 5, 1992
  1231.           samedi le 5 fevrier 1992      [/Lfr specified]
  1232.           Mittwoch, 5. Februar 1992     [/Lgr specified]
  1233.  
  1234. ddmn3yy   05Feb92
  1235.  
  1236. xxx       2CP  (...Dec 25, 1992)
  1237.           This format represents dates for the years 1990-2024 in 3
  1238.           characters of "extended hex" ("XX") notation.  For more on XX
  1239.           notation, see the discussion of the #2XX function.
  1240.  
  1241.           The first character is the XX representation of the number of
  1242.           years since 1990 (1990 = 0, 1991 = 1, etc.).  If you attempt to
  1243.           output a date outside of the 1990-2024 range in XXX format, Fdate
  1244.           will report an error (i.e. return "ERROR" and errorlevel of 1).
  1245.  
  1246.           The second and third characters contain the XX representation of
  1247.           the month-number and day-of-month-number, respectively.
  1248.  
  1249.           EXAMPLE: "1993 Feb  1"  is represented as  "321"
  1250.           EXAMPLE: "2000 Dec 25"  is represented as  "ACP".
  1251.  
  1252. -----------------------------------------------------------------------
  1253. NOTE that the following formats contain embedded spaces.  Consequently
  1254. they must be enclosed in double quotes. EXAMPLE: /O"mn zd, ccyy".
  1255. -----------------------------------------------------------------------
  1256. "zd mn ccyy"      5 February 1992
  1257. "zd mn, ccyy"     5 February, 1992
  1258. "zd. mn ccyy"     5. February 1992   [German-style date format]
  1259. "zd. mn3 ccyy"    5. Feb 1992        [German-style date format]
  1260. "mn3 dd ccyy"     Feb 05 1992
  1261. "mn3 dd, ccyy"    Feb 05, 1992
  1262. "mn zd, ccyy"     February 5, 1992
  1263.  
  1264.  
  1265.  
  1266. LEAP-YEAR FLAG OUTPUT FORMAT
  1267. ============================
  1268.  
  1269. LY              0     "1" if date occurs in a leapyear, otherwise "0".
  1270.  
  1271.                  365 + this number gives total number of days in the year.
  1272.                   28 + this number gives total number of days in February.
  1273.  
  1274.  
  1275.  
  1276.  
  1277. TIME OUTPUT FORMATS
  1278. ===================
  1279. See also: the section on the /T (parm /A time override) parameter.
  1280.  
  1281. t1            9:05 am
  1282.               9:05 pm
  1283.  
  1284. HH:MM        09:05      24-hour time, hours:minutes
  1285.              21:05
  1286. HHMM         0905
  1287.              2105
  1288.  
  1289. HH:MM:SS     21:05:30   24-hour time, hours:minutes:seconds
  1290. HHMMSS       210530
  1291.  
  1292.  
  1293. BUSINESS JULIAN DATE OUTPUT FORMATS
  1294. ===================================
  1295.  
  1296. These are formats for "business julian" dates: dates expressed as the
  1297. number of days from the beginning of the year, when January 1 is day 1.
  1298.  
  1299. EXAMPLES:
  1300.  
  1301.       DATE      BUSINESS JULIAN DATE
  1302.   -----------   --------------------
  1303.   Jan  5, 1993  93005
  1304.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1305.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1306.  
  1307.  
  1308. FORMAT        EXAMPLES      DISCUSSION
  1309. ------        ---------     -----------------------------
  1310.  
  1311. ccyyjjj       1992027       Jan 27, 1992
  1312.   yyjjj         92027       "Business Julian" date expressed as number
  1313.     jjj           027       of days since January 1 of the same year.
  1314.     zzj            27       Note leading zero suppression in "zzj".
  1315.  
  1316.  
  1317. ABSOLUTE DATE/TIME OUTPUT FORMATS
  1318. =================================
  1319. See also: the section on the /T (parm /A time override) parameter.
  1320.  
  1321.  
  1322. day#           727198       "Absolute date": date expressed as number
  1323.                             of days since January 1, 0001.
  1324.  
  1325. minute#         33088       "Absolute minutes": time expressed as number
  1326.                             of minutes  since midnight, January 1, 1990.
  1327.  
  1328. second#        633088       "Absolute seconds": time expressed as number
  1329.                             of seconds  since midnight, January 1, 1990.
  1330.  
  1331.  
  1332. Running FDATE with /O parameter for an "absolute time" produces a
  1333. number based on the current time of day and the date in the /A parm.
  1334.  
  1335. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1336.        FDATE /Ff /Atoday /Ominute#
  1337. it will produce the absolute minute for January 10, 1992 at 2 pm.
  1338.  
  1339. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1340.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#
  1341. it will produce the absolute minute for January 15, 1992 at 2 pm.
  1342.  
  1343.  
  1344. /T: TIME OVERRIDE PARAMETER
  1345. ===============================
  1346.  
  1347. You may override Fdate's use of the current time -- for the /A parameter
  1348. only -- by using the /T parameter.  The /T parameter specifies a time of
  1349. day in the 24-hour format hh:mm:ss (hours:minutes:seconds).  Leading zeros
  1350. in each of the three fields (hh, mm, ss) may be omitted.  The seconds field
  1351. may be omitted; if omitted, it defaults to "00".
  1352.  
  1353. Note that the /T parm overrides the time portion of the /A date, but it
  1354. does NOT override the time portion of the /B date.
  1355.  
  1356. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1357.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#  /T5:12
  1358. it will produce the absolute minute for January 15, 1992 at 5:12 am.
  1359.  
  1360. The most frequent and important use of the /T parm is with the format
  1361. function (/Ff) to obtain the "absolute" minute of a specific date and time. 
  1362. Once we have the absolute minutes of two different date/times, we can
  1363. easily obtain the time between them (expressed in days, hours, and minutes)
  1364. by using Fdate's #dif, #idiv, and #mod functions.  (In the EXAMPLES
  1365. section, see the example that contains FORATIME.BAT.)
  1366.  
  1367. It is also possible to use /T in conjunction with the time compare function
  1368. (/Ftcomp).
  1369.  
  1370. @echo ON
  1371. cls
  1372. rem  Since both /A and /B default to the current date and time,
  1373. rem  and since /T parm overrides the time only for the /A parm ...
  1374.  
  1375. rem   ... during daytime hours, this will always return LT
  1376. Fdate /ftcomp /T00:00:00
  1377. rem   ... during daytime hours, this will always return GT
  1378. Fdate /ftcomp /T23:59:59
  1379.  
  1380.  
  1381. HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE
  1382. ====================================================
  1383.  
  1384.  
  1385. CALL A BATCH FILE
  1386. =================
  1387.  
  1388.   The most basic way to put FDATE's output into an environment variable,
  1389.   although not the most convenient, is to:
  1390.   *  use the /P (prefix string) feature to create a DOS "SET" statement,
  1391.   *  redirect the output to a batch file, and then
  1392.   *  CALL the batch file.  
  1393.  
  1394.   Since CALL first appeared in DOS 3.3, you will need DOS 3.3 or greater
  1395.   to use this technique.
  1396.  
  1397.        FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET FDATE=" >JUNKTEMP.BAT
  1398.        call JUNKTEMP.BAT
  1399.        del  JUNKTEMP.BAT
  1400.  
  1401.  
  1402.  
  1403. USE AN ENVIRONMENT-MANIPULATION UTILITY
  1404. =======================================
  1405.  
  1406.   There are shareware and public domain utilities that are written
  1407.   specifically to manipulate environment variables, and do that job very
  1408.   well.  FDATE's output can be put into an environment variable by piping
  1409.   it to one of these utilities.  When piping FDATE output to a utility,
  1410.   you can prevent the output from being ECHOed to the screen by
  1411.   redirecting the output to NUL.
  1412.  
  1413.   Of these utilities, I can especially recommend Bob Stephan's GET
  1414.   (because it is very inexpensive and very powerful and flexible) and PC
  1415.   Magazine's STRINGS (free to ZiffNet members).  See the EXAMPLES section
  1416.   for examples of how to use STRINGS and GET to put FDATE's output into an
  1417.   environment variable.
  1418.  
  1419.      As of March 14, 1994, the current version of GET is 2.6.  On
  1420.      CompuServe, use IBMFF to look for GET25.ZIP (which contains version
  1421.      2.5 and the full documentation file) and GET26u.ZIP (the version 2.6
  1422.      update of GET, which contains version 2.6 of GET, but not the full
  1423.      documentation).  Look in CIS:IBMSYS, Library 1, or for GET.ZIP in
  1424.      ZNT:UTILFORUM, lib 16.  GET is also available from the Public Software
  1425.      Library in Houston.
  1426.  
  1427.      As of February 14, 1992, the current version of STRINGS is 1.3. On
  1428.      CompuServe, look for STRING.ZIP in the PC Magazine Utilities Lib of
  1429.      ZNT:UTILFORUM.  STRHYP.ZIP contains good hypertext documentation on
  1430.      STRINGS.
  1431.  
  1432. FDATE'S /V PARAMETER
  1433. ====================
  1434.  
  1435.   Manipulating the environment is an incredibly tricky business.  There
  1436.   are questions of the local versus master environment, the version of DOS
  1437.   you are running, and the environment under which you are running (DOS,
  1438.   Windows, QuarterDeck, Carousel).  In order to keep FDATE focussed on
  1439.   date-related issues, versions of Fdate prior to 6.1 did not attempt to
  1440.   put output directly into an environment variable.  Instead, FDATE's
  1441.   output was written to standard output, that is, it was displayed on the
  1442.   screen. Output could then be redirected to a batch file, or piped to a
  1443.   utility (such as STRINGS or GET), that would put the output into an
  1444.   environment variable.
  1445.  
  1446.   Starting with version 6.1, Fdate supports a /V (environment variable)
  1447.   parameter.  A user can use /V to tell Fdate to put its output directly
  1448.   into an environment variable in the "parent" environment.
  1449.  
  1450.   NOTE that due to the complexities of manipulating the environment, there
  1451.   may be circumstances where /V doesn't work.  These include running FDATE
  1452.   when you have shelled out to DOS from another program, have put the
  1453.   command processor in upper memory (UMB) (see below), are running under
  1454.   Carousel, etc.  In such cases, you may be able to use one of the more
  1455.   basic techniques described above.  For a list of environments in which
  1456.   the /V option has been reported as NOT working, see the next section.
  1457.  
  1458.  
  1459.  
  1460.   /Vevar tells Fdate to put output into an environmental variable whose
  1461.   name is "evar".  For example:
  1462.  
  1463.                 Fdate /Ff /Vdate1
  1464.  
  1465.   will set the environment variable DATE1 to the current date.  If you
  1466.   type SET at the DOS prompt, you should see something like:
  1467.  
  1468.                 DATE1=Friday February 14, 1992
  1469.  
  1470.   If you specify /V without an evar name, the evar name defaults to FDATE.
  1471.  
  1472.      Example :       Fdate /Ff /V
  1473.      produces:       FDATE=Friday February 14, 1992
  1474.  
  1475.   If you do not use /V, Fdate output is written to standard output, i.e.
  1476.   to the screen.
  1477.  
  1478. /V WHEN RUNNING UNDER MICROSOFT WINDOWS
  1479. =======================================
  1480.  
  1481. Starting with FDATE version 8.4 -- thanks to a Turbo Pascal routine from
  1482. the Turbo Professional library (see below) provided by Kim Kokkonen of
  1483. TurboPower Software -- FDATE's /V parameter works even in a Windows DOS
  1484. box, assuming you have enough environment space available.
  1485.  
  1486. Starting with Windows 3.1, Windows reads the SHELL= statement in your
  1487. CONFIG.SYS file and allocates the same amount of environment space to a DOS
  1488. window that you specify there.  I've found that using the SHELL= statement
  1489. to set the environment size to 512 bytes is adequate for all of my needs.
  1490.  
  1491. If you're running Windows 3.0, or earlier, you should upgrade immediately! 
  1492. Until then, always start Windows from a batch file that contains the
  1493. following line, executed BEFORE you start Windows:
  1494.  
  1495.    SET DUMMY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1496.  
  1497. This will reserve a chunk of environment space that will be copied into the
  1498. environment in the Windows DOS box.  Then, as one of the first statements
  1499. in any batch file that you run under Windows, put
  1500.  
  1501.    SET DUMMY=
  1502.  
  1503. This will free up the environment space used by all those "X"s.  For a good
  1504. treatment of running DOS apps under Windows, including a discussion of the
  1505. environment, I recommend Brian Livingston's WINDOWS 3.1 SECRETS (Ch. 7).
  1506.  
  1507. Turbo Professional: "Highly Recommended"
  1508.  
  1509.   If you do serious Turbo Pascal programming, you should have Turbo
  1510.   Professional or Object Professional library.  Turbo Professional is a
  1511.   library of about 600 routines to do all sorts of useful stuff in Turbo
  1512.   Pascal programs, including:
  1513.  
  1514.     CRT unit emulation, with many added features 
  1515.     Popup windows, virtual screens, and pulldown menu systems.
  1516.     Full screen data entry with formatting and data validation.
  1517.     Complete mouse support, keyboard macros, runtime error recovery.
  1518.     A context sensitive popup help unit.
  1519.     Units for picking from lists of items, including filenames.
  1520.     Easy and reliable ways to make your program memory resident.
  1521.     Interrupt service routine handlers, extended & expanded memory access.
  1522.     BCD arithmetic, including transcendental functions & the Form routine
  1523.     Sorting and searching.
  1524.     Extensive string manipulation & strings longer than 255 characters.
  1525.     Arrays larger than 64K (in RAM, EMS, or paged to disk)
  1526.  
  1527. For more information, call TurboPower at 1-800-333-4160 (9-5 Mountain
  1528. time), send CompuServe mail to 76004,2611, or visit the CompuServe
  1529. TurboPower forum in PCVENB section 6.
  1530.  
  1531. /V WHEN USING 4DOS, NDOS, AND UMB
  1532. =================================
  1533.     --------------------------------------------------------------
  1534.     I have received the following report from Aran Spence about
  1535.     circumstances in which FDATE /V will not set a variable
  1536.     in the master environment.  This report leads me to believe
  1537.     that FDATE /V may also fail to work with MS-DOS if you put
  1538.     the command processor or the environment in Upper Memory.
  1539.                     Note, however, that this behavior has not been tested
  1540.                     with FDATE 8.4's new environment-handling routines.
  1541.     --------------------------------------------------------------
  1542. Steve,
  1543.  
  1544. There are options with 4DOS and NDOS to load the environment and part
  1545. of the command processor into upper memory blocks.  When one of these
  1546. options is used, FDATE /V can't find the environment and produces the
  1547. message:
  1548.  
  1549.    ERROR
  1550.    echo ERROR: Master environment not found
  1551.    pause
  1552.  
  1553. If you have a 4DOS.INI file, it has to contain these lines for FDATE /V
  1554. to work:
  1555.  
  1556.    UMBEnvironment = No
  1557.    UMBLoad = No
  1558.  
  1559. If you have NDOS, the SHELL statement in CONFIG.SYS cannot contain
  1560. any reference to UMB loading via /U (which puts NDOS.COM in UMB), nor
  1561. can it contain a statement of the form:
  1562.                 /E:xxxU
  1563. (which puts xxx bytes of the environment in UMB via the "U" parameter).
  1564.  
  1565. Also, NSTART.BTM or 4START.BTM cannot contain
  1566.          SET NDSHELL=/e+xxxU /U
  1567. in which both U's represent UMB loading of the command processor and the
  1568. environment during secondary shells.
  1569.  
  1570. FDATE'S ERROR HANDLING
  1571. ======================
  1572.  
  1573.    If FDATE detects an error:
  1574.  
  1575.      (1) it will return an errorlevel of 1 (rather than 0), and
  1576.      (2) its output will be 3 lines:
  1577.        * the word ERROR
  1578.        * a DOS batch-file ECHO statement that displays an error message
  1579.        * a DOS batch-file PAUSE statement
  1580.  
  1581.    If Fdate output is displayed directly, or redirected to NUL,
  1582.    you can detect an error by testing the errorlevel for a value of 1.
  1583.  
  1584.    If Fdate output is piped to an environment manipulation utility such
  1585.    as STRINGS or GET, the environment variable will be set to ERROR.
  1586.    Errorlevel will be set by STRINGS/GET, and will probably be 0.
  1587.    In such a case, the only way to detect an error is to test the
  1588.    environment variable for the value ERROR.
  1589.  
  1590.    If FDATE output is redirected to a batch file, which is then
  1591.    CALLed to set an environment variable, the batch file will:
  1592.      * set the environment variable to ERROR,
  1593.      * ECHO the error message, and
  1594.      * pause.
  1595.    You can detect an error by testing errorlevel for the value 1
  1596.    either before or after you CALL the batch file, or 
  1597.    by testing the environment variable for the
  1598.    value ERROR, AFTER you have CALLed the batch file.
  1599.  
  1600. ----------------------------------------------------------------------
  1601.  
  1602.  EXAMPLE:
  1603.    rem use FDATE to check validity of year in parm %1
  1604.    Fdate /Fv /Imm-dd-ccyy /ATT-TT-%1 > nul
  1605.    if errorlevel 1 echo Year parm [%1] is not valid.
  1606.    if errorlevel 1 goto endit
  1607.  
  1608.  EXAMPLE:
  1609.    rem use GET with FDATE, to put FDATE output into into %year%
  1610.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy | GET ZE /V%year% >nul
  1611.    if (%year%)==(ERROR) echo Year parm [%1] is not valid.
  1612.    if (%year%)==(ERROR) goto endit
  1613.  
  1614.  EXAMPLE:
  1615.    rem use a batch file with FDATE, to put FDATE output into %year%
  1616.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy /P"@set year=">junktemp.bat
  1617.    call junktemp.bat
  1618.    del  junktemp.bat
  1619.    if errorlevel 1 echo Year parm [%1] is not valid.
  1620.    if errorlevel 1 goto endit
  1621.  
  1622. EXAMPLES OF HOW TO USE FDATE
  1623. ============================
  1624.  
  1625. :01 Display Fdate output on screen
  1626. :==================================================================
  1627. FDATE /Ff /At /Od1 /P"Today is "
  1628.  
  1629.  
  1630. :02 Redirect FDATE output to a file
  1631. :==================================================================
  1632. FDATE /Ff /At /Od1 /P"Today is " >FDATE.OUT
  1633.  
  1634.  
  1635. :03 Put FDATE output in an environment variable using a batch file
  1636. :==================================================================
  1637. FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET DATE1=" >JUNKTEMP.BAT
  1638. call JUNKTEMP.BAT
  1639. del  JUNKTEMP.BAT
  1640.  
  1641.  
  1642. :04 Put FDATE output in an environment variable using /V parm
  1643. :==================================================================
  1644. FDATE /Ff /Atoday /O"mn zd, ccyy" /Vdate1
  1645.  
  1646.  
  1647. :05 Put FDATE output in an environment variable using STRINGS
  1648. :==================================================================
  1649. FDATE /Ff /Atoday /O"mn zd, ccyy" |STRINGS date1= ASK >NUL
  1650.  
  1651.  
  1652. :06 Put FDATE output in an environment variable using GET
  1653. :==================================================================
  1654. FDATE /Ff /Atoday /O"mn zd, ccyy" |GET ZE /Vdate1 >NUL
  1655.  
  1656.  
  1657. :07 Get user input
  1658. :==================================================================
  1659. @echo off
  1660. cls
  1661. echo Enter a date in mm-dd-ccyy format for validation
  1662.  
  1663. :: get user input
  1664. fdate /fget /vUserDate1
  1665.  
  1666. :: validate user input using /Fv (validate function)
  1667. fdate /fv /A%UserDate1% >nul
  1668. if errorlevel 1 echo Invalid date: %UserDate1%
  1669. if errorlevel 1 goto endit
  1670.  
  1671. :: put your batch file processing here ...
  1672. echo Processing date: %UserDate1%
  1673.  
  1674. :endit
  1675. :: cleanup
  1676. set UserDate1=
  1677.  
  1678.  
  1679. :08 Get a user menu selection
  1680. :==================================================================
  1681. @echo off
  1682. :start
  1683. cls
  1684. echo ===========================================================
  1685. echo             MAKE A MENU SELECTION
  1686. echo ===========================================================
  1687. echo   A   DIR *.*
  1688. echo   B   DIR *.BAT
  1689. echo.
  1690. echo Press ESC to exit
  1691. echo.
  1692. echo ===========================================================
  1693. FDATE /FgetK /Q"Press letter of your choice> " /KABx /V
  1694.  
  1695. if (%FDATE%)==(A) goto Choice_%FDATE%
  1696. if (%FDATE%)==(B) goto Choice_%FDATE%
  1697. if (%FDATE%)==(x) goto endit
  1698. echo Program logic error.   Invalid choice [%FDATE%]
  1699. pause
  1700. goto Start
  1701.  
  1702. :CHOICE_A
  1703.  cls
  1704.  echo Processing choice %FDATE% ...
  1705.  DIR *.* /W /P
  1706.  pause
  1707.  goto Start
  1708.  
  1709. :CHOICE_B
  1710.  echo Processing choice %FDATE% ...
  1711.  DIR *.BAT /W /P
  1712.  pause
  1713.  goto Start
  1714.  
  1715. :endit
  1716. set choice=
  1717. cls
  1718.  
  1719.  
  1720. :10 Change a date from one format into another
  1721. :==================================================================
  1722. :: change date from mm-dd-yy format to ccyymmdd format
  1723. FDATE /Ff /Imm-dd-yy /A05-08-92 /Occyymmdd
  1724.  
  1725.  
  1726.  
  1727. :11 Find the difference in days between two dates
  1728. :==================================================================
  1729. FDATE /Fdif /Imm-dd-ccyy /A%date1% /B%date2% /vdiff
  1730. echo The difference is %diff% days.
  1731.  
  1732.  
  1733. :12 Find the elapsed days/hours/minutes between two date/times.
  1734. :===================================================================
  1735. This batch file was developed in cooperation with Walter Ledge, a sysop for
  1736. CompuServe's CRFORUM.  In addition to being a good example of how to use
  1737. Fdate's /T parm and "#idiv" function, it should be useful for other
  1738. CompuServe sysops who need to submit the same reports that Walt does. 
  1739. Here's Walt's message that started the whole thing.
  1740.  
  1741.   As an assistant sysop on the CRFORUM, I have to submit reports to CIS on
  1742.   the number of messages that are posted on our forum in terms of time per
  1743.   1,000 messages -- i.e., say, I know that 1,000 messages were posted
  1744.   between the hours of 17:05 on July 5 and 3:03 on July 7.  I need to know
  1745.   how many hours and minutes it took for those 1000 messages to be posted. 
  1746.   So I would like some way to use FDATE to calculate the difference
  1747.   between those two times (which, of course, include the dates).
  1748.  
  1749. FORATIM2.BAT is an improvement of the original FORATIME.BAT batch file. 
  1750. FORATIM2.BAT uses the /Fget function, which first appeared in Fdate 8.3, to
  1751. get user input from the terminal, rather than requiring all parameters to
  1752. be entered at the command line as FORATIME.BAT did. 
  1753.  
  1754.  
  1755. @echo off
  1756. cls
  1757. :: ------------------------------------------------------
  1758. :: FORATIM2.BAT batch file
  1759. ::
  1760. :: FUNCTION
  1761. ::    Calculate the elapsed time (in days and minutes)
  1762. ::    between some "begin" date/time and some "end" date/time
  1763. ::
  1764. :: ------------------------------------------------------
  1765. ECHO --------------------------------------------------------------
  1766. ECHO     Calculate elapsed time between two date/times
  1767. ECHO --------------------------------------------------------------
  1768.  
  1769. :BegDate
  1770. Fdate /Fget /VBEGdate /Q"Enter BEGIN DATE (mm-dd-ccyy): "
  1771. :BegTime
  1772. Fdate /Fget /VBEGtime /Q"Enter BEGIN TIME (hh:mm).....: "
  1773.  
  1774. :: validate date & time
  1775. fdate /fv /A%BEGdate% /T%BEGtime% >nul
  1776. if errorlevel 1 echo Invalid date/time
  1777. if errorlevel 1 goto BegDate
  1778.  
  1779. :: get absolute minute of start date/time.
  1780. fdate /ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
  1781. if errorlevel 1 goto BegTime
  1782. fdate /ff /ofull    /A%BEGdate% /T%BEGtime% /Vfull1
  1783.  
  1784. :
  1785. echo.
  1786. :EndDate
  1787. Fdate /Fget /VENDdate /Q"Enter END.. DATE (mm-dd-ccyy): "
  1788. :EndTime
  1789. Fdate /Fget /VENDtime /Q"Enter END.. TIME (hh:mm).....: "
  1790.  
  1791. :: validate date & time
  1792. fdate /fv /A%ENDdate% /T%ENDtime% >nul
  1793. if errorlevel 1 echo Invalid date/time
  1794. if errorlevel 1 goto EndDate
  1795.  
  1796. :: get absolute minute of end date/time.
  1797. fdate /ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
  1798. if errorlevel 1 goto EndTime
  1799. fdate /ff /ofull    /A%ENDdate% /T%ENDtime% /Vfull2
  1800.  
  1801. echo.
  1802. ECHO Calculating elapsed time...
  1803. :: calculate the difference between ABStime1 and ABStime2
  1804. fdate /f#dif  /A%ABStime1% /B%ABStime2% /VMinutes
  1805.  
  1806. :: calculate the number of hours in it took
  1807. fdate /f#Idiv  /A%minutes% /B60  /VHours
  1808.  
  1809. :: calculate the number of extra minutes it took
  1810. fdate /f#mod   /A%minutes% /B60  /VMins
  1811.  
  1812. echo.
  1813. echo   Between %full1%
  1814. echo       and %full2%
  1815. echo.
  1816. echo   Elapsed time was:
  1817. echo           %hours% hours and %mins% minutes
  1818.  
  1819. fdate /f#Idiv /A%minutes% /B1440 /Vday1
  1820. fdate /f#mod  /A%minutes% /B1440 /Vmin1
  1821. fdate /f#Idiv /A%min1%    /B60   /Vhour1
  1822. fdate /f#mod  /A%min1%    /B60   /Vmin2
  1823. echo   or
  1824. echo         %day1% day(s) %hour1% hour(s) and %min2% minute(s).
  1825. echo.
  1826. echo.
  1827. ::
  1828. :: cleanup
  1829. set ENDdate=
  1830. set BEGdate=
  1831. set BEGtime=
  1832. set ENDtime=
  1833. set full1=
  1834. set full2=
  1835. set minutes=
  1836. set ABStime1=
  1837. set ABStime2=
  1838. set day1=
  1839. set hour1=
  1840. set min1=
  1841. set min2=
  1842. set mins=
  1843. set hours=
  1844. :endit
  1845.  
  1846. :14 Time the execution of a piece of software
  1847. :==================================================================
  1848. COMMENT
  1849.   This example was developed before the addition of the #div and #idiv
  1850.   functions to Fdate, so the run time (in minutes) is not calculated by
  1851.   dividing the run time (in seconds) by 60, as it now could be.
  1852.  
  1853. @echo off
  1854. cls
  1855. ECHO The demo will run for 1 - 60 seconds.
  1856. echo.
  1857. ECHO ─────────────────────────────────────────────────────────────────────
  1858. ECHO CALCULATE HOW LONG IT TOOK TO RUN A PROGRAM (in seconds and minutes)
  1859. echo.
  1860. echo If you leave long batch files to run overnight, this technique can
  1861. echo be used to record how long each program in the batch file ran.
  1862. echo.
  1863. echo The technique for setting the values of environment variables in this
  1864. echo part of the demo uses temporary batch files and CALL statements.
  1865. echo If you have a program such as GET or STRINGS, you can use it instead.
  1866. ECHO ──────────────────────────────────────────────────────────────────────
  1867. echo.
  1868. PAUSE
  1869. cls
  1870.  
  1871. FDATE /Ff /At /Ohh:mm:ss /P"TESTPGM simulated execution begins at "
  1872.  
  1873. REM  GET PROGRAM BEGIN TIME, IN MINUTES
  1874. @set BegM=
  1875. @set EndM=
  1876. @set RunM=
  1877. FDATE /Ff /At /Ominute# /P"SET BegM=" >FDATJUNK.BAT
  1878. CALL FDATJUNK.BAT
  1879.  
  1880. REM  GET PROGRAM BEGIN TIME, IN SECONDS
  1881. set BegS=
  1882. set EndS=
  1883. set RunS=
  1884. FDATE /Ff /At /Osecond# /P"SET BegS=" >FDATJUNK.BAT
  1885. CALL FDATJUNK.BAT
  1886.  
  1887. rem ───────────────────────────────────────────────────────────────
  1888. rem [simulate execution of a program: loop for a minute or less]
  1889. rem [In a real batch file, you would put your program statements here]
  1890. rem ───────────────────────────────────────────────────────────────
  1891. :BegLoop
  1892.    FDATE /Ff /At /Osecond# /P"SET EndS=" >FDATJUNK.BAT
  1893.    CALL FDATJUNK.BAT
  1894.    FDATE /Ff /At /Ominute# /P"SET EndM=" >FDATJUNK.BAT
  1895.    CALL FDATJUNK.BAT
  1896.  
  1897.    rem  calculate run time (difference between start time and end time)
  1898.    FDATE /F#dif /A%EndM% /B%BegM% /P"SET RunM=" > FDATJUNK.BAT
  1899.    CALL FDATJUNK.BAT
  1900.  
  1901.    rem  calculate run time (difference between start time and end time)
  1902.    FDATE /F#dif /A%EndS% /B%BegS% /P"SET RunS=" > FDATJUNK.BAT
  1903.    CALL FDATJUNK.BAT
  1904.    echo      TESTPGM running, elapsed time: %RunS% seconds
  1905.  
  1906.    if (%RunM%)==()  goto EndLoop
  1907.    if (%RunM%)==(0) goto BegLoop
  1908. :EndLoop
  1909. rem ───────────────────────────────────────────────────────────────
  1910.  
  1911. REM  GET PROGRAM END TIME IN SECONDS
  1912. FDATE /Ff /At /Osecond# /P"SET EndS=" > FDATJUNK.BAT
  1913. CALL FDATJUNK.BAT
  1914.  
  1915. REM  GET PROGRAM END TIME IN MINUTES
  1916. FDATE /Ff /At /Ominute# /P"SET EndM=" > FDATJUNK.BAT
  1917. CALL FDATJUNK.BAT
  1918.  
  1919. FDATE /Ff /At /Ohh:mm:ss /P"TESTPGM simulated execution ends at "
  1920. echo.
  1921.  
  1922. echo TESTPGM: Program end   time (Absolute seconds): %EndS%
  1923. echo TESTPGM: Program begin time (Absolute seconds): %BegS%
  1924. rem  calculate run time (difference between start time and end time)
  1925. FDATE /F#dif /A%EndS% /B%BegS% /P"TESTPGM: Run time in seconds= "
  1926. set BegS=
  1927. set EndS=
  1928.  
  1929. echo.
  1930. echo TESTPGM: Program end   time (Absolute minutes): %EndM%
  1931. echo TESTPGM: Program begin time (Absolute minutes): %BegM%
  1932. rem  calculate run time (difference between start time and end time)
  1933. FDATE /F#dif /A%EndM% /B%BegM% /P"TESTPGM: Run time in minutes= "
  1934. DEL  FDATJUNK.BAT
  1935. set BegM=
  1936. set EndM=
  1937. set RunM=
  1938. set RunS=
  1939.  
  1940. :15 Find calendar date corresponding to a "business Julian" date
  1941. :==================================================================
  1942. rem business julian date is 1992:045.  Note input format CCYYjjj
  1943. FDATE /Ff /A1992045  /Iccyyjjj  /Od1
  1944.  
  1945. rem You don't need to left-zero-fill the day
  1946. FDATE /Ff /A199245  /Iccyyjjj  /Od1
  1947.  
  1948. rem You can assume the century, if you specify the YYjjj input format
  1949. FDATE /Ff /A9245  /Iyyjjj  /Od1
  1950.  
  1951. :16 Set your PC's date to a business julian date
  1952. :==================================================================
  1953. @echo off
  1954. goto enddoc
  1955. ---------------------------------------------------------------------
  1956. This batch file was created by Aran Spence [CIS: 70162,3044].  Its
  1957. function is to emulate the DOS DATE command, but allow the user to set
  1958. the date using a business julian date format (yyjjj) instead of
  1959. mm-dd-yy.
  1960.  
  1961. Note the format is YYjjj. This is the BUSINESS julian date: a date
  1962. expressed as the number of days from the beginning of the year,
  1963. when January 1 is day 1.
  1964.  
  1965.            date      BUSINESS julian date
  1966.        -----------   --------------------
  1967.        Jan 5, 1992       92005
  1968.        Jan 5, 1993       93005
  1969.        Dec 31, 1993      93365  [Dec 31 is 365th day of year 1993]
  1970.  
  1971. As Aran originally wrote it, the user-prompt was virtually identical to
  1972. that of the DATE command.  I have modified his original version, so it
  1973. now looks less like the DATE command but displays a bit more
  1974. information, and so it can operate from the command line.
  1975.  
  1976. If the user enters a business julian date as a command-line
  1977. parameter, JDATE resets the date to that julian date.
  1978.              EXAMPLE:  JDATE 92005
  1979. If there is no input parameter, /fget is used to prompt the user for a
  1980. date.
  1981.  
  1982. Note that the user must enter both of the year digits (yy),
  1983. but may enter an abbreviated set of day digits (jjj).  That is,
  1984. for julian day 92005, the user is permitted to enter 925.
  1985.  
  1986. One handy use for JDATE is simply to find out what the current
  1987. business julian date is.
  1988. ---------------------------------------------------------------------
  1989. :enddoc
  1990.  
  1991. SET NewJD=%1
  1992. if not (%NewJD%)==() goto GotDate
  1993.  
  1994. :ShowDate
  1995. Fdate /Ff /Od1    /P"Current Gregorian date: "
  1996. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  1997.  
  1998. :GetDate
  1999. GET S "Enter new date (yyddd): " /VNewJD /L
  2000. if (%NewJD%)==() goto endit
  2001.  
  2002. :GotDate
  2003. Fdate /Ff /A%NewJD% /Omm-dd-yy /Iyyjjj /VNewGD
  2004. if errorlevel 1 echo Invalid date "%NewJD%"
  2005. if errorlevel 1 goto GetDate
  2006.  
  2007. ::   reset the date
  2008. DATE %NewGD%
  2009.  
  2010. echo SYSTEM DATE HAS BEEN RESET
  2011. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2012. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2013.  
  2014. :endit
  2015. SET NewJD=
  2016. SET NewGD=
  2017. echo.
  2018.  
  2019. :18 Determine if parm %1 contains a valid date
  2020. :==================================================================
  2021. COMMENT
  2022.   Note that we throw away the FDATE output by redirecting it to NUL.  All
  2023.   we really want here is the errorlevel, which tells us whether or not the
  2024.   string in %1 is a valid year.
  2025.  
  2026. Fdate /Fv /Imm-dd-ccyy /A%1  >nul
  2027. if errorlevel 1 echo Parm 1 was not a valid date: %1
  2028. if errorlevel 1 goto endit
  2029.  
  2030. ::
  2031. :: Put the body of your batch file here.
  2032. ::
  2033.  
  2034. :endit
  2035.  
  2036.  
  2037.  
  2038. :19 "Roll your own" date format 
  2039. :==================================================================
  2040. echo Display date in custom-made format: yymn3dd
  2041. Fdate /Ff /Oyy              /V
  2042. Fdate /Ff /Omn3 /P"%fdate%" /V
  2043. Fdate /Ff /Odd  /P"%fdate%" /V
  2044.  
  2045. echo Today is %fdate%
  2046. set fdate=
  2047.  
  2048.  
  2049.  
  2050. :20 Find the 4th Thursday in November (Thanksgiving)
  2051. :==================================================================
  2052. Fdate /Fw /D5 /N4 /A11-01-%year% /Imm-dd-ccyy /Od1 /P"Thanksgiving: "
  2053.  
  2054.  
  2055. :22 On a date, show what anniversary it is for some event
  2056. :==================================================================
  2057. See HOLIDAYS.BAT demo batch file
  2058.  
  2059.  
  2060. :23 Show a list of holidays in a given year
  2061. :==================================================================
  2062. See HOLIDAYS.BAT demo batch file
  2063.  
  2064.  
  2065. :24 Show a list of Federal holidays in a given year
  2066. :==================================================================
  2067. See HOLIFEDS.BAT demo batch file
  2068.  
  2069. :25 Determine if a year is valid, and evenly divisible by 4
  2070. :==================================================================
  2071.  
  2072. @echo off
  2073. cls
  2074. echo FUNCTION: Accept a year parm (CCYY) as parameter 1.  Determine if
  2075. echo the year is an election or inauguration year in the United States.
  2076. echo ===================================================================
  2077.  
  2078. rem verify %1 is a valid year
  2079. Fdate /Fv /Imm-dd-ccyy /A01-01-%1 >nul
  2080. if errorlevel 1 echo Year parm [%1] is not valid.
  2081. if errorlevel 1 goto endit
  2082.  
  2083. Fdate /Ff /Imm-dd-ccyy /A01-01-%1 /p"@set year=">junktemp.bat
  2084. call junktemp.bat
  2085.  
  2086. Fdate /F#mod /A%1 /B4 /p"@set mod=">junktemp.bat
  2087. call junktemp.bat
  2088. if (%mod%)==(0) echo %1 is an American presidential election year.
  2089. if (%mod%)==(1) echo %1 is an American presidential inauguration year.
  2090. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an election year.
  2091. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an inauguration year.
  2092.  
  2093. set mod=
  2094. :endit
  2095. if exist junktemp.bat del  junktemp.bat
  2096.  
  2097.  
  2098.  
  2099.  
  2100. :30 Compare a file's date to today's date
  2101. :==================================================================
  2102. rem Compare today's date to the date on the filename in %1
  2103. Fdate /Fcomp /At /If /B%1 /Vcomp
  2104. if (%comp%)==(EQ) echo %1 was created or updated today
  2105. set comp=
  2106.  
  2107.  
  2108. :31 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS
  2109. :==================================================================
  2110. COMMENT
  2111. There are many ways to check errorlevels.  This example shows 
  2112. several of them.
  2113.  
  2114. @echo off
  2115. cls
  2116. SET F1=FDATE.BAT
  2117. SET F2=FDATE.EXE
  2118. fdate /FTcomp /If /A%f1%  /B%F2% /P"%f1% is " /S" %f2%"
  2119.  
  2120. if errorlevel 101 if not errorlevel 103 echo %f1% is LT/EQ %f2%
  2121. if errorlevel 102                       echo %f1% is GT/EQ %f2%
  2122.  
  2123. if errorlevel 101 if not errorlevel 102 echo %f1% is older than %f2%
  2124. if errorlevel 102 if not errorlevel 103 echo %f1% is same age as %f2%
  2125. if errorlevel 103 if not errorlevel 104 echo %f1% is younger than %f2%
  2126.  
  2127. if errorlevel 101 if not errorlevel 103 echo %f1% at least as old as %f2%
  2128. if errorlevel 102                       echo %f1% is no older than %f2%
  2129.  
  2130. if errorlevel 101 if not errorlevel 102 echo errorlevel is 101
  2131. if errorlevel 102 if not errorlevel 103 echo errorlevel is 102
  2132. if errorlevel 103 if not errorlevel 104 echo errorlevel is 103
  2133. SET F1=
  2134. SET F2=
  2135. :endit
  2136.  
  2137.  
  2138.  
  2139. :32 Display a list of all files that were created/updated today. 
  2140. :==================================================================
  2141. @echo off
  2142. if (%1)==(SUBROUTINE) goto %2
  2143.  
  2144. CLS
  2145. ECHO FILES MEETING FILESPEC [%1] THAT WERE CREATED OR UPDATED TODAY
  2146. REM  The batch file calls itself: Its own name is in parm %0
  2147. for %%v in (%1) do  CALL %0 SUBROUTINE CHECKFILE %%v
  2148.  
  2149. set comp=
  2150. goto endit
  2151.  
  2152. :CHECKFILE
  2153. shift
  2154. shift
  2155.  
  2156. rem Compare today's date to the date on the %1 file
  2157. Fdate /Fcomp /If /A%1 /Vcomp  
  2158.  
  2159. rem echo the filename if the file was created/updated today
  2160. if (%comp%)==(EQ) echo %1
  2161. :endit
  2162.  
  2163. :33 Delete files more than X days old (use a batch-file subroutine)
  2164. :==================================================================
  2165. See the COMMENTARY that follows the text of the batch file.
  2166.  
  2167.  
  2168. @echo off
  2169. if (%1)==(SUBROUTINE) goto %2
  2170. cls
  2171.  
  2172. goto EndDoc
  2173. ----------------------------------------------------------------------
  2174. OLDFILES.BAT
  2175. This batch file shows how to do work on files that are older than
  2176. %NumDays%.  The PROCESS! subroutine can be modified to do any kind of
  2177. work you want.
  2178. ----------------------------------------------------------------------
  2179. :EndDoc
  2180.  
  2181. :: set the number of days in the past.   if this value is not passed
  2182. :: in via parameter %1, it defaults to 3 days
  2183. set NumDays=%1
  2184. if (%NumDays%)==() SET NumDays=3
  2185.  
  2186.  
  2187. echo ------------------------------------------------------------------
  2188. echo           PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
  2189. echo ------------------------------------------------------------------
  2190. for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2191. echo ------------------------------------------------------------------
  2192. echo           END OF PROCESSING
  2193. echo ------------------------------------------------------------------
  2194.  
  2195. :: CLEANUP
  2196. set NumDays=
  2197. set DaysOld=
  2198. set Comparison=
  2199. GOTO ENDIT
  2200.  
  2201. :
  2202. :PROCESS!
  2203. shift
  2204. shift
  2205.  
  2206. :: get difference in days between filedate and today.
  2207. :: Note that /B parm (which is omitted) defaults to today's date.
  2208. fdate /fdif   /A%1        /IF          /VDaysOld
  2209.  
  2210. :: compare DaysOld to NumDays
  2211. fdate /f#comp /A%DaysOld% /B%NumDays%  /Vcomparison
  2212.  
  2213. :: the following line will DISPLAY THE NAME AND AGE OF
  2214. :: any file for which %DaysOld% is greater than %NumDays%
  2215. :: --------------------------------------------------------------
  2216. if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
  2217.  
  2218. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2219. :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
  2220. :: any file for which %DaysOld% is greater than %NumDays%
  2221. :: -----------------------------------------------
  2222. REM if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
  2223.  
  2224. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2225. :: the following line will DELETE
  2226. :: any file for which %DaysOld% is greater than %NumDays%
  2227. :: -----------------------------------------------
  2228. REM if (%comparison%)==(GT) DEL %1
  2229.  
  2230. :: fall through to endit
  2231.  
  2232. :endit
  2233.  
  2234.  ===============================================================
  2235.                         COMMENTARY BEGIN
  2236.  ===============================================================
  2237.  This batch file uses a crude, but effective, technique for giving a
  2238.  batch file the ability to call subroutines.  If you've never seen
  2239.  something like this before, it is sort of mind-blowing.  Here's some
  2240.  commentary on the more important lines involved in the technique.
  2241.  ===============================================================
  2242.  
  2243.  if (%1)==(SUBROUTINE) goto %2
  2244.  
  2245.     COMMENTARY:
  2246.     If the first parameter, %1, is "SUBROUTINE", then the batch file
  2247.     recognizes that it is being called for the purpose of executing
  2248.     one of its own subroutines.  In such a case, it does a GOTO to the
  2249.     start of the requested subroutine.  That is, it goes to the label
  2250.     whose name is in the second parameter.
  2251.  
  2252.     Explicitly specifying the name of the desired subroutine permits
  2253.     permits us to have multiple subroutines in the batch file,
  2254.     each with its own name.  (As it happens, in this batch file
  2255.     we have only one subroutine, named "PROCESS!")
  2256.  
  2257.     If the first parameter is not "SUBROUTINE", then we fall through
  2258.     and begin executing the main routine of the batch file.  In such a
  2259.     case, the first parameter (%1) may contain a number, indicating
  2260.     the number of days to use in determining which files to delete.
  2261.  
  2262.     Note that this technique will make the batch file malfunction
  2263.     if the user himself ever executes the batch file from the
  2264.     DOS command line with the word "SUBROUTINE" as the first
  2265.     parameter, the word "PROCESS!" as the second parameter, and a
  2266.     third parameter that is missing or not a valid filename.
  2267.     This is so unlikely, however, that it is reasonable
  2268.     to assume that it will never happen.
  2269.  
  2270.  ===============================================================
  2271.  
  2272.  for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2273.  
  2274.     COMMENTARY:
  2275.     In a batch file, %0 contains the name by which the batch file was
  2276.     invoked.  We use this fact to allow a batch file to call itself,
  2277.     regardless of what name the user has given to it.
  2278.  
  2279.     The first parameter passed, when the batch file calls
  2280.     itself, is the string "SUBROUTINE".  This string allows the batch
  2281.     file to recognize when it is being called for the purpose of
  2282.     executing one of its own subroutines.
  2283.  
  2284.     The second parameter is the name of the subroutine that we want
  2285.     to call: in this case, "PROCESS!".
  2286.  
  2287.     The third parameter is what we would normally think of as the first
  2288.     parameter to the subroutine.  In this case, when the
  2289.     FOR statement is executed, and the substitution for %%v takes
  2290.     place, it will contain the name of the file to be processed.
  2291.     Note that we could, if we wished, pass additional parameters to
  2292.     the subroutine.  Note also that we can control the files that
  2293.     we process.  We do so via the filemask in the FOR statement.
  2294.     It we used, for example, "*.EXE", then we would process only
  2295.     executable files.
  2296.  
  2297.  ===============================================================
  2298.  
  2299.  GOTO ENDIT
  2300.  
  2301.    COMMENTARY:
  2302.    When the mainline of the batch file is finished executing, we
  2303.    goto the end of the batch file.  We MUST do this GOTO in order
  2304.    to avoid falling through into, and starting to execute, the first
  2305.    of the batch file's subroutines.
  2306.  
  2307.  ===============================================================
  2308.  
  2309.  :PROCESS!
  2310.  shift
  2311.  shift
  2312.  
  2313.    COMMENTARY:
  2314.    Note that when the batch file is called as a subroutine, and the
  2315.    batch file goes to the PROCESS! label, the values of the parms are:
  2316.            %0 = [the name of the batch file]
  2317.            %1 = SUBROUTINE
  2318.            %2 = PROCESS!
  2319.            %3 = [name of the file to be processed]
  2320.  
  2321.     We shift all the parameters to the left twice, to move the
  2322.     parameter(s) into what we think of as the
  2323.     proper places for parameters to the subroutine.
  2324.  
  2325.     After the first SHIFT command:
  2326.            %0 = SUBROUTINE
  2327.            %1 = PROCESS!
  2328.            %2 = [name of the file to be processed]
  2329.  
  2330.     After the second SHIFT command:
  2331.            %0 = PROCESS!
  2332.            %1 = [name of the file to be processed]
  2333.  
  2334.     Now %1 contains what we think of as the proper parameter(s)
  2335.     to the subroutine.  In this case, %1 contains the filename that
  2336.     we want the subroutine to process.
  2337.  
  2338.     At the end of every subroutine, there should be a GOTO ENDIT,
  2339.     which causes the batch file to go to its own end, and then
  2340.     end and return control to the statement in the program which called
  2341.     it.  (This is, of course, the CALL statement embedded in the
  2342.     FOR statement.)
  2343.  
  2344.     We can optimize the batch file a little by omitting the "goto endit"
  2345.     at the end of the last subroutine.  Instead, we simply allow the
  2346.     last subroutine to fall through to the end of the batch file.
  2347.  
  2348.  ===============================================================
  2349.                          COMMENTARY END
  2350.  ===============================================================
  2351.  
  2352. :34 Loop through an array of environment variables
  2353. :======================================================================
  2354. @echo off
  2355. cls
  2356. SET pct=%%%
  2357. SET prefix=Address
  2358.  
  2359. ECHO LOADING AN ARRAY
  2360. SET subscript=1
  2361. SET %prefix%.%subscript%=Stephen Ferg
  2362. SET subscript=2
  2363. SET %prefix%.%subscript%=5113 N. 8th Road
  2364. SET subscript=3
  2365. SET %prefix%.%subscript%=Arlington, VA 22205
  2366.  
  2367. ECHO UNLOADING AND DISPLAYING THE ARRAY
  2368. SET subscript=1
  2369. :LoopTop
  2370. REM do while subscript less than/equal 3
  2371. if %subscript%==4 goto LoopEnd
  2372.  
  2373.    REM put value of subscripted variable into tempvar
  2374.    ECHO SET tempvar=%pct%%prefix%.%subscript%%pct%>JUNKTEMP.BAT
  2375.    CALL JUNKTEMP.BAT
  2376.  
  2377.    REM display value of subscripted variable
  2378.    ECHO %prefix%.%subscript% is: %tempvar%
  2379.  
  2380.    REM delete subscripted variable
  2381.    SET %prefix%.%subscript%=
  2382.  
  2383.    REM increment the loop variable
  2384.    Fdate /F#add /A%subscript% /B1 /Vsubscript
  2385.    goto LoopTop
  2386. :LoopEnd
  2387.  
  2388. SET pct=
  2389. SET tempvar=
  2390. SET prefix=
  2391. SET subscript=
  2392. DEL JUNKTEMP.BAT
  2393.  
  2394. :44 Do something on the last day (or last Friday) of the month
  2395. :==================================================================
  2396. COMMENT
  2397. We often need batch files that do some special task on the last day of the
  2398. month: run a backup job, display a reminder message, etc.  This example
  2399. batch file, LASTDAY.BAT, simply displays a message -- you can modify it to
  2400. do whatever it is that YOU want to do.
  2401.  
  2402. If you plan to run LASTDAY.BAT at work, and you work Monday through Friday,
  2403. then checking for the last day of the month would be a poor strategy --
  2404. after you leave work on a Friday, the last day of the month might occur on
  2405. the following Saturday or Sunday.   So I've included a check to see if the
  2406. Friday is the last working day of the month.  If you don't want that
  2407. functionality, deleting the lines between the first and last occurrence of
  2408. the string "EndCheck" will remove it.
  2409. =======================================================================
  2410.  @echo off
  2411.  REM ---------------------------------------------------------------
  2412.  REM check to see if today is the last day of the month
  2413.  REM ---------------------------------------------------------------
  2414.  REM get today's month
  2415.  fdate /ff        /omm /vmmtoday
  2416.  
  2417.  REM get tomorrow's month
  2418.  fdate /fadd /n1 /omm  /vmmtomorrow
  2419.  
  2420.  REM if tomorrow occurs in a different month,
  2421.  REM then today is the last day of this month
  2422.  if not (%mmtoday%)==(%mmtomorrow%) echo LAST DAY OF THE MONTH
  2423.  if not (%mmtoday%)==(%mmtomorrow%) goto EndCheck
  2424.  
  2425.  REM -------------------------------------------------------------
  2426.  REM check to see if today is the last Friday of the month
  2427.  REM -------------------------------------------------------------
  2428.  rem get today's day of the week, to see if it is Friday
  2429.  fdate /ff /odow3 /vdow3
  2430.  if not (%dow3%)==(Fri) goto EndCheck
  2431.  
  2432.  REM today is Friday.  Get next Monday's month
  2433.  fdate /fadd /n3 /omm  /vmmMonday
  2434.  
  2435.  REM if next Monday occurs in a different month,
  2436.  REM then today is the last Friday of this month
  2437.  if not (%mmtoday%)==(%mmMonday%) echo LAST WORKING DAY OF THE MONTH
  2438.  
  2439.  :EndCheck
  2440.  
  2441.  REM cleanup
  2442.  set dow3=
  2443.  set mmtoday=
  2444.  set mmtomorrow=
  2445.  set mmMonday=
  2446.  
  2447. :45 Get information about the month prior to the current month
  2448. :==================================================================
  2449. COMMENT
  2450. When running a monthly backup job at the beginning of the month, one often
  2451. needs to identify the previous month, or the last day of the previous
  2452. month.  Here's how to use Fdate to obtain that sort of information. 
  2453. Basically, we subtract one day from the first day of the current month,
  2454. giving us the last day of the previous month.
  2455. =======================================================================
  2456. @echo off
  2457. cls
  2458. : The simplest way to get information about last month is to subtract
  2459. : 1 day from the first day of this month ...
  2460.  
  2461. fdate /fsub /n1 /att-01-tttt /omm   /p"Last month was.................: "
  2462. fdate /fsub /n1 /att-01-tttt /occyy /p"Last month occurred in the year: "
  2463. fdate /fsub /n1 /att-01-tttt /odd   /p"The last day of last month was : "
  2464. fdate /fsub /n1 /att-01-tttt /od1   /p"The last day of last month was : "
  2465.  
  2466. :50 Represent a date in 3 bytes of "extended hex" notation
  2467. :==================================================================
  2468.  
  2469. rem produce today's date as 3 bytes
  2470. fdate /ff /oxxx 
  2471.  
  2472. rem produce yesterday's date in xxx format
  2473. fdate /fsub /N1 /oxxx
  2474.  
  2475.  
  2476.  
  2477.  
  2478. :51 Represent a date in a short (4-byte) format (technique #1)
  2479. :==================================================================
  2480. COMMENT
  2481. A common use of Fdate is to format today's date and use it to rename a file
  2482. (typically a log file of some sort).  You may wish to store the date
  2483. information in as few characters as possible, in order to maximize the
  2484. number of other characters in the filename that you can use to store other
  2485. information.
  2486.  
  2487. In this example, and the next one, I illustrate two ways to store a date in
  2488. 4 bytes.
  2489.  
  2490.  
  2491. The simplest way is to represent today's date as a 4-digit number.
  2492. To do this, we first pick a base date:  I'll use January 1, 1990.
  2493. Then it is a simple matter to calculate the number of days between today
  2494. and the base date:
  2495.  
  2496.            FDATE /Fdif /at /b01-01-1990 
  2497.  
  2498. Starting in 1993, this will always generate a 4-digit number, and will
  2499. continue to do so for 20 years, until approximately the year 2003.  Dates
  2500. before 1993 may produce 1-, 2-, or 3-digit numbers, and dates after 2003
  2501. will begin to produce 5-digit numbers.  But this technique will work quite
  2502. nicely for most ordinary purposes for the next 20 years.  
  2503.  
  2504. If you're still using DOS in the year 2003, then in 2003 you can switch to
  2505. using January 1, 2000 as your base date and function quite nicely for the
  2506. next 20 years after that.
  2507.  
  2508. :52 Represent a date in a short (4-byte) format (technique #2)
  2509. :==================================================================
  2510. @echo off
  2511. cls
  2512. goto end-doc
  2513. ------------------------------------------------------------------
  2514. This batch file shows how to use Fdate's #2XX function to
  2515. obtain and represent today's date in 4 characters, YYMD, where:
  2516.  
  2517.   YY is the year (e.g. "93" for 1993)
  2518.    M is the month in extended hexadecimal (XX) notation
  2519.    D is the day-of-the-month in extended hexadecimal (XX) notation
  2520.  
  2521. You can also use Fdate's "XXX" output format to represent dates between
  2522. 1990 and 2024 in 3 bytes of extended hex notation.
  2523. ------------------------------------------------------------------
  2524. :end-doc
  2525.  
  2526. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE MONTH
  2527. Fdate /ff    /Omm   /Vmm
  2528. Fdate /f#2xx /A%mm% /Vmm
  2529. echo XX representation of this month's number      is %mm%
  2530.  
  2531. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE DAY
  2532. Fdate /ff    /Odd   /Vdd
  2533. Fdate /f#2xx /A%dd% /Vdd
  2534. echo XX representation of today's day of the month is %dd%
  2535.  
  2536. REM CONCATENATE THEM TO THE 2-CHARACTER REPRESENTATION FOR THE YEAR
  2537. Fdate /Ff /Oyy /S%mm%%dd% /Vdate
  2538. echo XX representation of today's full date        is %date%
  2539.  
  2540. REM CLEANUP
  2541. set mm=
  2542. set dd=
  2543. set date=
  2544. :endit
  2545.  
  2546.  
  2547.  
  2548. :53 Convert numbers to "extended hex" (XX) format
  2549. :==================================================================
  2550. @echo off
  2551. cls
  2552. SET decnum=0
  2553. :top
  2554.    if (%decnum%)==(37) goto endit
  2555.    fdate /f#2xx /A%decnum% /P"XX representation of %decnum% is "
  2556.    fdate /f#add /A%decnum% /b1 /Vdecnum
  2557. goto top
  2558.  
  2559. :endit
  2560.  
  2561. :54 Customize Fdate for a language of your choice
  2562. :==================================================================
  2563. @echo off
  2564. cls
  2565. goto end-doc
  2566. ------------------------------------------------------------------
  2567. You can use Fdate with a customized batch file to obtain the names of
  2568. the days of the week and the months in a language of your choice.  Or
  2569. you could use it to obtain names in uppercase, or the first 5
  2570. characters of the names (rather than the first three), or some other
  2571. customized formatting of your choice.)
  2572.  
  2573. I've invented a language called Fergian, which has its own names for
  2574. the days of the week, and the months.  In the following examples, I
  2575. invoke FERGIAN.BAT to make the translation.  The text of FERGIAN.BAT,
  2576. which does the real work here, is given in the next example.
  2577. ------------------------------------------------------------------
  2578. :end-doc
  2579.  
  2580. fdate /ff /omm /v
  2581. call Fergian mm- result %Fdate%
  2582. echo Month  is          %result%
  2583.  
  2584. fdate /ff  /omm /v
  2585. call Fergian mm3 result %Fdate%
  2586. echo Month3 is          %result%
  2587.  
  2588. fdate /ff /odow#  /v
  2589. call Fergian dw- result %Fdate%
  2590. echo Day of week  is    %result%
  2591.  
  2592. fdate /ff /odow#  /v
  2593. call Fergian dw3 result %Fdate%
  2594. echo Day of week3 is    %result%
  2595.  
  2596. REM cleanup
  2597. set Fdate=
  2598. set result=
  2599.  
  2600. :55 Fergian.BAT (used in the previous example)
  2601. :==================================================================
  2602. @echo off
  2603. set  %2=
  2604. goto %1
  2605.  
  2606. goto end-doc
  2607. --------------------------------------------------------------------
  2608. This batch file converts a month number, or day of the week number,
  2609. to a name in the FERGIAN language.
  2610. You can copy this batch file and customize it, to make it translate
  2611. into some other language of your choice.
  2612.  
  2613. This batch file expects the following parameters:
  2614.  
  2615. %1 contains the type of number you want to convert:
  2616.    MM- if you want the entire name of the month
  2617.    MM3 if you want the first 3 letters of the name of the month
  2618.  
  2619.    DW- if you want the entire name of the day of the week
  2620.    DW3 if you want the first 3 letters of the name of the day of the week
  2621.  
  2622. %2 contains the name of the environment variable that you
  2623.    want to use to hold the result
  2624.  
  2625. %3 contains the number that you want to convert
  2626. --------------------------------------------------------------------
  2627. :end-doc
  2628.  
  2629. :MM-
  2630. if (%3)==(01) set %2=Jaded
  2631. if (%3)==(02) set %2=Febrile
  2632. if (%3)==(03) set %2=Martial
  2633. if (%3)==(04) set %2=Abigail
  2634. if (%3)==(05) set %2=Maybelene
  2635. if (%3)==(06) set %2=Junkaroo
  2636. if (%3)==(07) set %2=Julia
  2637. if (%3)==(08) set %2=Augmentation
  2638. if (%3)==(09) set %2=Separation
  2639. if (%3)==(10) set %2=Ostentation
  2640. if (%3)==(11) set %2=Novelty
  2641. if (%3)==(12) set %2=Decadence
  2642. goto endit
  2643.  
  2644. :
  2645. :MM3
  2646. if (%3)==(01) set %2=Jad
  2647. if (%3)==(02) set %2=Feb
  2648. if (%3)==(03) set %2=Mar
  2649. if (%3)==(04) set %2=Abi
  2650. if (%3)==(05) set %2=May
  2651. if (%3)==(06) set %2=Jun
  2652. if (%3)==(07) set %2=Jul
  2653. if (%3)==(08) set %2=Aug
  2654. if (%3)==(09) set %2=Sep
  2655. if (%3)==(10) set %2=Ost
  2656. if (%3)==(11) set %2=Nov
  2657. if (%3)==(12) set %2=Dec
  2658. goto endit
  2659.  
  2660. :DW-
  2661. if (%3)==(1) set %2=SunDay
  2662. if (%3)==(2) set %2=MoonDay
  2663. if (%3)==(3) set %2=TwickasDay
  2664. if (%3)==(4) set %2=WodensDay
  2665. if (%3)==(5) set %2=ThorsDay
  2666. if (%3)==(6) set %2=FreyasDay
  2667. if (%3)==(7) set %2=SaturnDay
  2668. goto endit
  2669.  
  2670.  
  2671. :DW3
  2672. if (%3)==(1) set %2=Sun
  2673. if (%3)==(2) set %2=Moo
  2674. if (%3)==(3) set %2=Twi
  2675. if (%3)==(4) set %2=Wod
  2676. if (%3)==(5) set %2=Tho
  2677. if (%3)==(6) set %2=Fre
  2678. if (%3)==(7) set %2=Sat
  2679. goto endit
  2680.  
  2681. :endit
  2682.  
  2683. :61 DO-ONCE: Run apps when booting for the first time of the day
  2684. :===============================================================
  2685. COMMENT
  2686.   Put this code in AUTOEXEC.BAT.  Note that this batch code requires DOS
  2687.   3.3+, since it uses CALL.
  2688.  
  2689. if not exist C:\LASTRUN.BAT goto RunNow
  2690.  
  2691. rem call LASTRUN.BAT, which will set an environment variable, %LASTRUN%,
  2692. rem that will contain the date when this batch file was last run.
  2693. rem ------------------------------------------------------------------
  2694. call C:\LASTRUN.BAT
  2695.  
  2696. rem compare the date in %LASTRUN% to today's date
  2697. rem ------------------------------------------------------------------
  2698. Fdate /Fcomp /At /B%LastRun% /Vcomp
  2699.  
  2700. : Today's date may be less than %LASTRUN% if you reset the system clock
  2701. IF (%COMP%)==(LT) goto NoRun
  2702. : If %LASTRUN% was the same as today's date,
  2703. :   then this batch file has already been run once today
  2704. IF (%COMP%)==(EQ) goto NoRun
  2705.  
  2706. : Daily processing hasn't been run today. Run it.
  2707. : Here, you should put the batch-file body --
  2708. : the code to run the applications that you want to run once per day
  2709. :
  2710.  
  2711. : ------------------------------------------------------------------
  2712. : Save today's date in a new version of LastRun.BAT.  Note that
  2713. : this code will be executed only if daily processing runs to
  2714. : completion without hanging the machine or aborting the batch file.
  2715. : ------------------------------------------------------------------
  2716. Fdate /Ff /Omm-dd-ccyy /At /P"@set LastRun=">LastRun.BAT
  2717.  
  2718. :NoRun
  2719. set LastRun=
  2720. set COMP=
  2721.  
  2722. :62 Run specific software, depending on the day of the week
  2723. :==================================================================
  2724. COMMENT
  2725. This is a very common use for Fdate.  I use it to load an alarm-clock TSR
  2726. (Terminate and Stay Resident, "memory resident", program) that beeps at me
  2727. (at different times on different days of the week) to remind me that it is
  2728. time to attend a meeting that is regularly scheduled for that day of the
  2729. week.
  2730.  
  2731. Note that stuff for a given day of the week will be executed every time you
  2732. boot up on that day of the week.  If you want stuff (e.g. a backup job) to
  2733. be run only once (the first time you boot up) on a given day of the week,
  2734. then:
  2735.  
  2736. (1)  copy the code from DO-ONCE (the previous example) into your
  2737.      AUTOEXEC.BAT file, then
  2738.  
  2739. (2)  copy this code into the body of the DO-ONCE code that you copied into
  2740.      AUTOEXEC.BAT in the last step.  If you do that, then this code will be
  2741.      run only once per day, even if you boot up multiple times per day.
  2742.  
  2743. Remember that if you are executing other batch files from a batch file, 
  2744. you should invoke them with a CALL statement:
  2745.               CALL batchfilename parm1 parm2 ...
  2746. so control will return to the calling batch file when execution of the
  2747. called batch file is complete.      
  2748.  
  2749. Note that the string comparison is case sensitive.
  2750. ==================================================================
  2751.  
  2752. :: get 3-character day-of-week name and put it in DOW e-var
  2753. FDATE /ff /oDOW3 /vDOW
  2754.  
  2755. if (%DOW%)==(Mon) alarmTSR.exe 10:30 Time for Monday staff meeting
  2756.  
  2757. if (%DOW%)==(Fri) echo Running Friday backup.  Please wait...
  2758. if (%DOW%)==(Fri) CALL BACKUP C: 
  2759. if (%DOW%)==(Fri) CALL BACKUP D: 
  2760. set dow=
  2761.  
  2762.  
  2763.  
  2764. :63 Run a program at a specified time later in the day
  2765. :==================================================================
  2766. COMMENT
  2767.   This batch file involves a lot of disk activity because DOS re-reads the
  2768.   batch file from disk every time it does a GOTO LOOPTOP.  You can avoid
  2769.   all this disk activity by running the batch file from a RAM DISK.
  2770.  
  2771. REM GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
  2772. FDATE /Ff /At /Ominute#  |STRINGS RunTime= ASK >NUL
  2773.  
  2774. REM ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
  2775. FDATE /F#add /A%RunTime% /B120 |STRINGS RunTime= ASK >NUL
  2776.  
  2777. REM LOOP UNTIL NOWTIME HAS REACHED RUNTIME
  2778. :LoopTop
  2779.   FDATE /Ff /At  /Ominute#   |STRINGS NowTime=  ASK >NUL
  2780.   FDATE /F#comp  /A%NowTime% /B%RunTime% |STRINGS TimeComp= ASK >NUL
  2781.   if (%TimeComp%)==(LT) goto loopTop
  2782. :LoopEnd
  2783.  
  2784. echo STARTING EXECUTION OF APPLICATION: [program name]
  2785.  
  2786.  
  2787.  
  2788. :66 Change a filename to contain today's date in first 3 bytes
  2789. :==================================================================
  2790. FDATE /Ff /Oxxx /vXXX
  2791. ren  BACKUP.LOG  %XXX%-BACK.LOG
  2792. SET  XXX=
  2793.  
  2794.  
  2795.  
  2796. :67 Change a file's name to a name that contains today's date
  2797. :==================================================================
  2798. FDATE /Ff /At /Oyymmdd /vdate1
  2799. ren  BACKUP.LOG  BK%DATE1%.LOG
  2800. SET  DATE1=
  2801.  
  2802.  
  2803.  
  2804. :68 Change a file's name to a name containing an absolute minute 
  2805. :===============================================================
  2806. COMMENT
  2807.   This is a way to keep a complete series of files, such as log files,
  2808.   that are all created with the same name on the same day.  The only
  2809.   requirement is that they be created at least one minute apart.  You
  2810.   won't need to be able to decipher the absolute minute to figure out when
  2811.   the file was created; you can simply do a DIR on the file and look at
  2812.   its date/time stamp.  
  2813.  
  2814. FDATE /FF /At /Ominute# /VJulMin
  2815. REN online.log %JulMin%.log
  2816. SET JulMin=
  2817.  
  2818.  
  2819.  
  2820. :71 Extract the rightmost n characters of a string 
  2821. :===============================================================
  2822. rem extract the rightmost 6 characters of a string
  2823. FDATE /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  2824.  
  2825. HOW FDATE THINKS ABOUT DATES
  2826. ============================
  2827.  
  2828. FDATE'S BUSINESS VIEW OF THE CALENDAR
  2829. =====================================
  2830.  
  2831.   FDATE is intended for business applications, not historical ones.  
  2832.  
  2833.   FDATE does not take into account historical changes in the calendar such
  2834.   as the ten days that were dropped from the British calendar when Britain
  2835.   moved from the Julian to the Gregorian calendar in the 18th century, or
  2836.   the 11 days that were dropped from the Russian calendar when Russia made
  2837.   the same move in the early 20th century.
  2838.  
  2839.   As far as FDATE is concerned, the calendar has followed the same
  2840.   pattern, unchanged, since January 1, 0001.
  2841.  
  2842.  
  2843. FDATE'S BASE DATE
  2844. =================
  2845.   Internally, Fdate's date manipulations are based on translating a
  2846.   calendar date into an "absolute" or "TRUE Julian" date:  a date
  2847.   expressed as the number of days from some day in the distant past.
  2848.  
  2849.   FDATE's base date is January 1, 0001 (i.e. day 1 of month 1 of year 1)
  2850.   FDATE's absolute date for January 1, 0001 is      1.
  2851.   FDATE's absolute date for January 1, 1992 is 727198.
  2852.  
  2853.  
  2854. FDATE'S LEAP YEAR ALGORITHM
  2855. ===========================
  2856.     Every year evenly divisible by 4 IS a leap year
  2857.       EXCEPT THAT
  2858.         Every year evenly divisible by 100 IS NOT a leap year
  2859.           EXCEPT THAT
  2860.             Every year evenly divisible by 400 IS a leap year
  2861.     .
  2862.     Using this algorithm
  2863.          1983  is not a leap year
  2864.          1984  is     a leap year
  2865.          1900  is not a leap year
  2866.          2000  is     a leap year
  2867.  
  2868.     See "A Machine Algorithm for Processing Calendar Dates", by
  2869.          Henry F. Fliegel (Georgetown University Observatory) and
  2870.          Thomas C. Van Flandern (U.S. Naval Observatory)
  2871.          COMMUNICATIONS OF THE ACM, Volume 11, Number 10, October 1968
  2872.  
  2873. There is supposedly a new adjustment to the leapyear algorithm,
  2874. which specifies the additional exception:
  2875.  
  2876.               EXCEPT THAT
  2877.                 Every year evenly divisible by 4000 IS a leap year
  2878.  
  2879. See "Bit By Bit" column, COMPUTER LANGUAGE, November 1989, p. 148.
  2880. This adjustment is not part of FDATE's leapyear algorithm.
  2881. Unless your application is working with dates 2,000 years in the
  2882. future, the lack of this exception will be irrelevant for you.
  2883.  
  2884. FDATE'S CENTURY-ASSUMPTION ALGORITHM
  2885. ====================================
  2886. If an input date is supplied in a format in which the year is
  2887. specified without a century -- that is, as YY rather than CCYY --
  2888. then Fdate does not automatically use the current century.
  2889. Instead,
  2890.  
  2891.    *  if YY is greater than 20,       then FDATE assumes CC = 19
  2892.    *  if YY is less than or equal 20, then FDATE assumes CC = 20
  2893.  
  2894. Examples:
  2895.          21    becomes  1921
  2896.          ...
  2897.          99    becomes  1999
  2898.          00    becomes  2000
  2899.          01    becomes  2001
  2900.          ...
  2901.          20    becomes  2020
  2902. but then (again)
  2903.          21    becomes  1921
  2904.  
  2905. To put it simply, FDATE makes what would be a reasonable assumption
  2906. about the century for someone operating in the 1990's: it looks back to
  2907. 1921 and forward to 2020.  If both I and FDATE are still alive in the
  2908. year 2000, I'll probably update FDATE's century-assumption algorithm to
  2909. shift it forward several decades.
  2910.  
  2911.  
  2912. FDATE'S IMPLEMENTATION LIMITS
  2913. ====================================
  2914. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  2915. which means that Fdate can accept numbers up to 9 digits long.
  2916.  
  2917. DISTRIBUTION ISSUES
  2918. ===================
  2919.  
  2920. USE, REGISTRATION, AND DISTRIBUTION OF FDATE
  2921. ============================================
  2922.  
  2923. FDATE is freeware, or what is known as "zero-cost shareware".  FDATE is not
  2924. what is technically called "public domain" software because the author
  2925. retains the copyright.  FDATE can, however, be copied, used, and
  2926. distributed freely as long as FDATE.EXE and its associated doc file
  2927. (FDATE.DOC) and demonstration batch files and doc files (HOLIDAYS.BAT,
  2928. HOLIFEDS.BAT, HOLIFEDS.DOC) are not altered and are distributed together.  
  2929.  
  2930. There is no requirement to register FDATE in any way.
  2931.  
  2932. FDATE can be included in shareware packages as long as both FDATE and
  2933. its related files are included in the shareware package.
  2934.  
  2935. If you have received FDATE as part of some larger shareware package,
  2936. please be aware that you may freely use, copy, and distribute FDATE
  2937. without paying a fee for, or registering, the larger package.
  2938.  
  2939. The author explicitly disavows any claim whatsoever about the
  2940. correctness or functionality of FDATE, its documentation, and its
  2941. demonstration batch files, and disclaims liability for anything and
  2942. everything bad that might happen in connection with, before, during, or
  2943. after using it.  I have tried to make FDATE work right, but everybody
  2944. makes mistakes, so you use FDATE at your own risk.
  2945.  
  2946. I don't know if people will find FDATE useful, and I'd like to find
  2947. out.  If you find FDATE useful and use it on a regular basis, I'd
  2948. appreciate it if you would drop me a short note via US mail or
  2949. CompuServe, telling me about how you are using FDATE.
  2950.  
  2951. If you need other input/output formats, please contact the author.
  2952.  
  2953.  
  2954. TECHNICAL SUPPORT FOR FDATE
  2955. ===============================================
  2956.  
  2957. Send me a message via CompuServe mail; I'll respond.  When sending your
  2958. message, please let me know what version of Fdate you're using.
  2959.  
  2960.  
  2961. WHERE TO FIND THE MOST CURRENT VERSION OF FDATE
  2962. ===============================================
  2963.  
  2964. You will always be able to find the most recent version of FDATE on
  2965. CompuServe.  The filename will be FDATE.ZIP, and it will be available in
  2966. the CIS:IBMSYS forum (library 1, the "DOS Utilities" library).
  2967.  
  2968. If you have problems finding it, try using cross-library searching, looking
  2969. for the filename FDATE.ZIP or the keyword FDATE.
  2970.  
  2971.  
  2972. UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS
  2973. ===============================================
  2974.  
  2975. Feel free to post copies of FDATE.ZIP on any BBS that you wish, but please
  2976. do not upload it to any CompuServe library.  As long as I am the only one
  2977. putting copies of FDATE onto CompuServe, we can keep confusion over
  2978. versions to a minimum.
  2979.  
  2980. I distribute all versions of FDATE in a files called FDATE.ZIP, rather than
  2981. embedding information about the version in the file name.  I think doing
  2982. this helps newer versions of FDATE to force older versions out of
  2983. circulation.  To give a BBS user information about the version, I always
  2984. identify the version of FDATE in the 1-line file description that most BBSs
  2985. support.  
  2986.  
  2987.  
  2988. CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE
  2989. ===========================================
  2990.  
  2991. The current distribution package (FDATE.ZIP) contains the following:
  2992.  
  2993.        FDATE.EXE         [the FDATE program]
  2994.        FDATE.DOC         [this file, documentation for FDATE]
  2995.  
  2996.   [demonstration batch files]
  2997.        HOLIDAYS.BAT
  2998.        HOLIFEDS.BAT and HOLIFEDS.DOC
  2999.  
  3000. RECENT FDATE REVISION HISTORY
  3001. =============================
  3002.  
  3003. Letters appended to version numbers indicate modifications to
  3004. the doc files, without any modification to the FDATE.EXE software.
  3005. Asterisks (*) indicate most important changes in the new version.
  3006.  
  3007. 7.0a   Nov 14, 1992
  3008.        Added #mod function
  3009.        Major reformatting of documentation to make it more user-friendly
  3010.    
  3011. 7.1a   Apr 15, 1993
  3012.        Added German language support.  Thanks for the request, and the
  3013.        necessary information, from Patrick Schmucki, via the Active-Net
  3014.        BBS in Rapperswil, Switzerland.
  3015.  
  3016. 8.0    July, 1993
  3017.        Added "V" (validate) and "m" (month addition/subtraction) functions
  3018.        Added math functions: #mult #div #idiv
  3019.        Added /T (time) parameter
  3020.  
  3021.        Added FORATIME.BAT example, which Walter Ledge (assistant sysop of
  3022.        CompuServe's CRFORUM) and I developed.  A big thanks to Walt for
  3023.        his feedback and help.
  3024.  
  3025. 8.1    July 27, 1993  BUG FIX
  3026.        An error-trapping routine that was added to version 7.9 contained a
  3027.        bug that caused Fdate's numeric math functions (#add, #dif, #mult,
  3028.        #div, #idiv, #mod, #comp, etc.) to return incorrect results. 
  3029.        
  3030. 8.2    August, 1993
  3031.        Removed FILEDATE.BAT from the distribution .ZIP file.
  3032.  
  3033.        Corrected the Spanish and French "full" and "d1" output formats. 
  3034.        Thanks for the information on Spanish and French date formats to
  3035.        Gene J. Raymond, of GJR Software Products.
  3036.  
  3037. 8.3a   Feb 24, 1994
  3038.  
  3039. *      Added the following string-handling functions:
  3040.        get    (get user input)
  3041.        getu   (get uppercase user input)
  3042.        upper  (uppercase a string)
  3043.        len    (length of a string)
  3044.        substr (substring)
  3045.  
  3046. *      Added /F#2xx (convert number to extended hex format) function. 
  3047.        Deleted SETXX.BAT, which has been made obsolete with the addition
  3048.        of this new function.  Modified second example of storing a 4-digit
  3049.        date to use #2xx instead of SETXX.BAT.
  3050.  
  3051. *      Added output formats "ddmmccyy" and "ddmmyy" at the request of
  3052.        several users.
  3053.  
  3054. *      Added output format "xxx" after several requests for advice on how
  3055.        to represent a large range of dates in a minimum number of bytes
  3056.        (usually for constructing filenames from today's date).
  3057.  
  3058. *      At the request of several users, enhanced the "compare" functions
  3059.        (comp, tcomp, #comp) so they set distinctive errorlevels for their
  3060.        different results.  See the table of contents ("COMPARE-FUNCTION
  3061.        ERRORLEVELS") and EXAMPLES.
  3062.  
  3063.        To discussion of /Fv parameter, added note about almost always
  3064.        redirecting output to NUL when using /Fv.
  3065.  
  3066.        Revised FORATIME.BAT example batch file to make error-correction a
  3067.        bit more robust and to add better documentation on how to use it.
  3068.  
  3069.        Added example batch files to use new functions, especially
  3070.        FORATIM2.BAT which uses new "get" function
  3071.  
  3072.        Removed FDATEX.BAT demonstration batch file from distribution
  3073.        package, to reduce its size.  The examples in this DOC file should
  3074.        make the examples in FDATEX.BAT unnecessary
  3075.  
  3076.  
  3077. 8.4a   March 20, 1994
  3078. *      Added GETK (get keypress) function
  3079.  
  3080. *      Added ability to use /V when running in a Windows DOS box, thanks
  3081.        to a Turbo Pascal routine from the Turbo Professional library
  3082.        provided by Kim Kokkonen of TurboPower Software.
  3083.  
  3084.        Fixed a bug in which the prompt string (/Q) for the GET and GETU
  3085.        functions was being written to redirectable output (StdOut).  The
  3086.        prompt string is now written directly to the screen, and will not
  3087.        appear in FDATE's output when the output is redirected to a file.
  3088.  
  3089.        Removed ALARM.BAT, ALARM.DOC, TIC.BAT and TIC.DOC from distribution
  3090.        package.  They were too esoteric to be generally helpful.
  3091.  
  3092.        Added FILE_ID.DIZ and DESC.SDI to distribution package.
  3093.  
  3094.        Corrected algorithm for Mardi Gras in HOLIDAYS.BAT.  Modified
  3095.        HOLIDAYS.BAT and HOLIFEDS.BAT to make them more interactive, using
  3096.        FDATE's new abilities to get user input.
  3097.  
  3098. *      Started ZIPing FDATE.ZIP with PKZIP 2.04g rather than version 1.1
  3099.  
  3100. 8.4b   April 2, 1994
  3101.        Revised example :08, to use /fgetK rather than /fgetU
  3102.        Fixed formatting of #dif function
  3103.        Reformatted examples to reduce number of printed pages
  3104.        Duplicate example :07 was renumbered 
  3105.        FORATIME.BAT (original version) removed as no longer interesting
  3106.        Modified JDATE.BAT to use new /Fget function
  3107.